aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/action_util.c3
-rw-r--r--quantum/basic_profiling.h2
-rw-r--r--quantum/bits.h33
-rw-r--r--quantum/color.c19
-rw-r--r--quantum/color.h43
-rw-r--r--quantum/command.c5
-rw-r--r--quantum/haptic.c2
-rw-r--r--quantum/joystick.c10
-rw-r--r--quantum/joystick.h22
-rw-r--r--quantum/keyboard.c7
-rw-r--r--quantum/keycodes.h47
-rw-r--r--quantum/layer_lock.c100
-rw-r--r--quantum/layer_lock.h98
-rw-r--r--quantum/led_matrix/animations/breathing_anim.h15
-rw-r--r--quantum/led_matrix/led_matrix.c17
-rw-r--r--quantum/led_matrix/led_matrix.h2
-rw-r--r--quantum/logging/debug.h5
-rw-r--r--quantum/os_detection.c58
-rw-r--r--quantum/os_detection.h2
-rw-r--r--quantum/os_detection/tests/os_detection.cpp14
-rw-r--r--quantum/painter/qp.h6
-rw-r--r--quantum/painter/qp_internal.c1
-rw-r--r--quantum/painter/rules.mk27
-rw-r--r--quantum/pointing_device/pointing_device.c71
-rw-r--r--quantum/pointing_device/pointing_device.h32
-rw-r--r--quantum/pointing_device/pointing_device_drivers.c514
-rw-r--r--quantum/process_keycode/process_combo.c52
-rw-r--r--quantum/process_keycode/process_connection.c36
-rw-r--r--quantum/process_keycode/process_connection.h9
-rw-r--r--quantum/process_keycode/process_haptic.c2
-rw-r--r--quantum/process_keycode/process_layer_lock.c82
-rw-r--r--quantum/process_keycode/process_layer_lock.h21
-rw-r--r--quantum/process_keycode/process_rgb.c226
-rw-r--r--quantum/process_keycode/process_rgb.h22
-rw-r--r--quantum/process_keycode/process_underglow.c119
-rw-r--r--quantum/quantum.c47
-rw-r--r--quantum/quantum.h5
-rw-r--r--quantum/quantum_keycodes_legacy.h2
-rw-r--r--quantum/rgb_matrix/animations/alpha_mods_anim.h6
-rw-r--r--quantum/rgb_matrix/animations/breathing_anim.h17
-rw-r--r--quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/colorband_sat_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/colorband_spiral_val_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/colorband_val_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/cycle_all_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/cycle_left_right_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/cycle_out_in_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/cycle_pinwheel_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/cycle_spiral_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/cycle_up_down_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/dual_beacon_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/flower_blooming_anim.h8
-rw-r--r--quantum/rgb_matrix/animations/gradient_left_right_anim.h6
-rw-r--r--quantum/rgb_matrix/animations/gradient_up_down_anim.h6
-rw-r--r--quantum/rgb_matrix/animations/hue_breathing_anim.h4
-rw-r--r--quantum/rgb_matrix/animations/hue_pendulum_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/hue_wave_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/jellybean_raindrops_anim.h28
-rw-r--r--quantum/rgb_matrix/animations/pixel_flow_anim.h6
-rw-r--r--quantum/rgb_matrix/animations/pixel_fractal_anim.h6
-rw-r--r--quantum/rgb_matrix/animations/pixel_rain_anim.h25
-rw-r--r--quantum/rgb_matrix/animations/rainbow_beacon_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/raindrops_anim.h6
-rw-r--r--quantum/rgb_matrix/animations/riverflow_anim.h18
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h4
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h4
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_i.h4
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_reactive.h4
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h10
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h4
-rw-r--r--quantum/rgb_matrix/animations/solid_color_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_cross.h2
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_nexus.h2
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_simple_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_wide.h2
-rw-r--r--quantum/rgb_matrix/animations/solid_splash_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/splash_anim.h2
-rw-r--r--quantum/rgb_matrix/animations/starlight_anim.h4
-rw-r--r--quantum/rgb_matrix/animations/starlight_dual_hue_anim.h4
-rw-r--r--quantum/rgb_matrix/animations/starlight_dual_sat_anim.h4
-rw-r--r--quantum/rgb_matrix/animations/typing_heatmap_anim.h4
-rw-r--r--quantum/rgb_matrix/rgb_matrix.c23
-rw-r--r--quantum/rgb_matrix/rgb_matrix.h5
-rw-r--r--quantum/rgb_matrix/rgb_matrix_drivers.c58
-rw-r--r--quantum/rgb_matrix/rgb_matrix_types.h2
-rw-r--r--quantum/rgblight/rgblight.c190
-rw-r--r--quantum/rgblight/rgblight.h3
-rw-r--r--quantum/rgblight/rgblight_drivers.c20
-rw-r--r--quantum/rgblight/rgblight_drivers.h5
-rw-r--r--quantum/split_common/transactions.c10
-rw-r--r--quantum/util.h1
97 files changed, 1045 insertions, 1286 deletions
diff --git a/quantum/action_util.c b/quantum/action_util.c
index 52171b5050..c0dc4f3822 100644
--- a/quantum/action_util.c
+++ b/quantum/action_util.c
@@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_layer.h"
#include "timer.h"
#include "keycode_config.h"
+#include "usb_device_state.h"
#include <string.h>
extern keymap_config_t keymap_config;
@@ -318,7 +319,7 @@ void send_nkro_report(void) {
*/
void send_keyboard_report(void) {
#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
+ if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
send_nkro_report();
} else {
send_6kro_report();
diff --git a/quantum/basic_profiling.h b/quantum/basic_profiling.h
index d371acd6f0..e0a88d49cf 100644
--- a/quantum/basic_profiling.h
+++ b/quantum/basic_profiling.h
@@ -25,8 +25,6 @@
# define TIMESTAMP_GETTER TCNT0
#elif defined(PROTOCOL_CHIBIOS)
# define TIMESTAMP_GETTER chSysGetRealtimeCounterX()
-#elif defined(PROTOCOL_ARM_ATSAM)
-# error arm_atsam not currently supported
#else
# error Unknown protocol in use
#endif
diff --git a/quantum/bits.h b/quantum/bits.h
new file mode 100644
index 0000000000..2f3c343762
--- /dev/null
+++ b/quantum/bits.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#pragma once
+
+#include <stdint.h>
+
+/* Remove these once we transitioned to C23 across all platfroms */
+#define UINT32_WIDTH 32
+#define UINT64_WIDTH 64
+
+/**
+ * @brief Mask for the little endian nth bit (0-31) in a 32-bit integer.
+ */
+#define BIT32(n) (UINT32_C(1) << (n))
+
+/**
+ * @brief Mask for the little endian nth bit (0-63) in a 64-bit integer.
+ */
+#define BIT64(n) (UINT64_C(1) << (n))
+
+/**
+ * @brief Create a contiguous 32-bit wide bitmask starting at bit position @l
+ * and ending at position @h. The range is inclusive, meaning GENMASK32(20, 10)
+ * gives us the 32-bit mask 0x001ffc00.
+ */
+#define GENMASK32(h, l) (((~UINT32_C(0)) - (UINT32_C(1) << (l)) + 1) & (~UINT32_C(0) >> (UINT32_WIDTH - 1 - (h))))
+
+/**
+ * @brief Create a contiguous 64-bit wide bitmask starting at bit position @l
+ * and ending at position @h. The range is inclusive, meaning GENMASK64(39, 21)
+ * gives us the 64-bit mask 0x000000ffffe00000.
+ */
+#define GENMASK64(h, l) (((~UINT64_C(0)) - (UINT64_C(1) << (l)) + 1) & (~UINT64_C(0) >> (UINT64_WIDTH - 1 - (h))))
diff --git a/quantum/color.c b/quantum/color.c
index 96d548a33c..93564784f0 100644
--- a/quantum/color.c
+++ b/quantum/color.c
@@ -19,8 +19,8 @@
#include "progmem.h"
#include "util.h"
-RGB hsv_to_rgb_impl(HSV hsv, bool use_cie) {
- RGB rgb;
+rgb_t hsv_to_rgb_impl(hsv_t hsv, bool use_cie) {
+ rgb_t rgb;
uint8_t region, remainder, p, q, t;
uint16_t h, s, v;
@@ -97,7 +97,7 @@ RGB hsv_to_rgb_impl(HSV hsv, bool use_cie) {
return rgb;
}
-RGB hsv_to_rgb(HSV hsv) {
+rgb_t hsv_to_rgb(hsv_t hsv) {
#ifdef USE_CIE1931_CURVE
return hsv_to_rgb_impl(hsv, true);
#else
@@ -105,17 +105,6 @@ RGB hsv_to_rgb(HSV hsv) {
#endif
}
-RGB hsv_to_rgb_nocie(HSV hsv) {
+rgb_t hsv_to_rgb_nocie(hsv_t hsv) {
return hsv_to_rgb_impl(hsv, false);
}
-
-#ifdef WS2812_RGBW
-void convert_rgb_to_rgbw(rgb_led_t *led) {
- // Determine lowest value in all three colors, put that into
- // the white channel and then shift all colors by that amount
- led->w = MIN(led->r, MIN(led->g, led->b));
- led->r -= led->w;
- led->g -= led->w;
- led->b -= led->w;
-}
-#endif
diff --git a/quantum/color.h b/quantum/color.h
index b6a9dd0641..5c23b25335 100644
--- a/quantum/color.h
+++ b/quantum/color.h
@@ -74,43 +74,24 @@
// clang-format on
-#define WS2812_BYTE_ORDER_RGB 0
-#define WS2812_BYTE_ORDER_GRB 1
-#define WS2812_BYTE_ORDER_BGR 2
-
-#ifndef WS2812_BYTE_ORDER
-# define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
-#endif
-
-typedef struct PACKED rgb_led_t {
-#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
- uint8_t g;
- uint8_t r;
- uint8_t b;
-#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
+typedef struct PACKED rgb_t {
uint8_t r;
uint8_t g;
uint8_t b;
-#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
- uint8_t b;
- uint8_t g;
- uint8_t r;
-#endif
-#ifdef WS2812_RGBW
- uint8_t w;
-#endif
-} rgb_led_t;
+} rgb_t;
-typedef rgb_led_t RGB;
+// DEPRECATED
+typedef rgb_t RGB;
+typedef rgb_t rgb_led_t;
-typedef struct PACKED HSV {
+typedef struct PACKED hsv_t {
uint8_t h;
uint8_t s;
uint8_t v;
-} HSV;
+} hsv_t;
+
+// DEPRECATED
+typedef hsv_t HSV;
-RGB hsv_to_rgb(HSV hsv);
-RGB hsv_to_rgb_nocie(HSV hsv);
-#ifdef WS2812_RGBW
-void convert_rgb_to_rgbw(rgb_led_t *led);
-#endif
+rgb_t hsv_to_rgb(hsv_t hsv);
+rgb_t hsv_to_rgb_nocie(hsv_t hsv);
diff --git a/quantum/command.c b/quantum/command.c
index c188638eb4..024d96917d 100644
--- a/quantum/command.c
+++ b/quantum/command.c
@@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "led.h"
#include "command.h"
#include "quantum.h"
+#include "usb_device_state.h"
#include "version.h"
#ifdef BACKLIGHT_ENABLE
@@ -230,8 +231,8 @@ static void print_status(void) {
"timer_read32(): %08lX\n"
, host_keyboard_leds()
- , keyboard_protocol
- , keyboard_idle
+ , usb_device_state_get_protocol()
+ , usb_device_state_get_idle_rate()
#ifdef NKRO_ENABLE
, keymap_config.nkro
#endif
diff --git a/quantum/haptic.c b/quantum/haptic.c
index 6a466293a7..81bad469b3 100644
--- a/quantum/haptic.c
+++ b/quantum/haptic.c
@@ -36,7 +36,7 @@ extern uint8_t split_haptic_play;
haptic_config_t haptic_config;
static void update_haptic_enable_gpios(void) {
- if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) {
+ if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED))) {
#if defined(HAPTIC_ENABLE_PIN)
HAPTIC_ENABLE_PIN_WRITE_ACTIVE();
#endif
diff --git a/quantum/joystick.c b/quantum/joystick.c
index 32f19b2cd9..62893fd199 100644
--- a/quantum/joystick.c
+++ b/quantum/joystick.c
@@ -29,6 +29,9 @@ joystick_t joystick_state = {
0
#endif
},
+#ifdef JOYSTICK_HAS_HAT
+ .hat = -1,
+#endif
.dirty = false,
};
@@ -145,6 +148,13 @@ void joystick_set_axis(uint8_t axis, int16_t value) {
}
}
+#ifdef JOYSTICK_HAS_HAT
+void joystick_set_hat(int8_t value) {
+ joystick_state.hat = value;
+ joystick_state.dirty = true;
+}
+#endif
+
void joystick_init(void) {
joystick_init_axes();
}
diff --git a/quantum/joystick.h b/quantum/joystick.h
index 5a69ceac64..24f80c1ad6 100644
--- a/quantum/joystick.h
+++ b/quantum/joystick.h
@@ -52,6 +52,16 @@
#define JOYSTICK_MAX_VALUE ((1L << (JOYSTICK_AXIS_RESOLUTION - 1)) - 1)
+#define JOYSTICK_HAT_CENTER -1
+#define JOYSTICK_HAT_NORTH 0
+#define JOYSTICK_HAT_NORTHEAST 1
+#define JOYSTICK_HAT_EAST 2
+#define JOYSTICK_HAT_SOUTHEAST 3
+#define JOYSTICK_HAT_SOUTH 4
+#define JOYSTICK_HAT_SOUTHWEST 5
+#define JOYSTICK_HAT_WEST 6
+#define JOYSTICK_HAT_NORTHWEST 7
+
// configure on input_pin of the joystick_axes array entry to NO_PIN
// to prevent it from being read from the ADC. This allows outputting forged axis value.
#define JOYSTICK_AXIS_VIRTUAL \
@@ -73,7 +83,10 @@ extern joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT];
typedef struct {
uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1];
int16_t axes[JOYSTICK_AXIS_COUNT];
- bool dirty;
+#ifdef JOYSTICK_HAS_HAT
+ int8_t hat;
+#endif
+ bool dirty;
} joystick_t;
extern joystick_t joystick_state;
@@ -129,4 +142,11 @@ void joystick_read_axes(void);
*/
void joystick_set_axis(uint8_t axis, int16_t value);
+/**
+ * \brief Set the position of the hat switch.
+ *
+ * \param value The hat switch position to set.
+ */
+void joystick_set_hat(int8_t value);
+
/** \} */
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index df1dc1c3ee..d7836cf36e 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -140,6 +140,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef OS_DETECTION_ENABLE
# include "os_detection.h"
#endif
+#ifdef LAYER_LOCK_ENABLE
+# include "layer_lock.h"
+#endif
static uint32_t last_input_modification_time = 0;
uint32_t last_input_activity_time(void) {
@@ -655,6 +658,10 @@ void quantum_task(void) {
#ifdef SECURE_ENABLE
secure_task();
#endif
+
+#ifdef LAYER_LOCK_ENABLE
+ layer_lock_task();
+#endif
}
/** \brief Main task that is repeatedly called as fast as possible. */
diff --git a/quantum/keycodes.h b/quantum/keycodes.h
index f461e4a586..e9da5105ce 100644
--- a/quantum/keycodes.h
+++ b/quantum/keycodes.h
@@ -72,6 +72,8 @@ enum qk_keycode_ranges {
QK_STENO_MAX = 0x74FF,
QK_MACRO = 0x7700,
QK_MACRO_MAX = 0x777F,
+ QK_CONNECTION = 0x7780,
+ QK_CONNECTION_MAX = 0x77BF,
QK_LIGHTING = 0x7800,
QK_LIGHTING_MAX = 0x78FF,
QK_QUANTUM = 0x7C00,
@@ -620,6 +622,21 @@ enum qk_keycode_defines {
QK_MACRO_29 = 0x771D,
QK_MACRO_30 = 0x771E,
QK_MACRO_31 = 0x771F,
+ QK_OUTPUT_AUTO = 0x7780,
+ QK_OUTPUT_NEXT = 0x7781,
+ QK_OUTPUT_PREV = 0x7782,
+ QK_OUTPUT_NONE = 0x7783,
+ QK_OUTPUT_USB = 0x7784,
+ QK_OUTPUT_2P4GHZ = 0x7785,
+ QK_OUTPUT_BLUETOOTH = 0x7786,
+ QK_BLUETOOTH_PROFILE_NEXT = 0x7790,
+ QK_BLUETOOTH_PROFILE_PREV = 0x7791,
+ QK_BLUETOOTH_UNPAIR = 0x7792,
+ QK_BLUETOOTH_PROFILE1 = 0x7793,
+ QK_BLUETOOTH_PROFILE2 = 0x7794,
+ QK_BLUETOOTH_PROFILE3 = 0x7795,
+ QK_BLUETOOTH_PROFILE4 = 0x7796,
+ QK_BLUETOOTH_PROFILE5 = 0x7797,
QK_BACKLIGHT_ON = 0x7800,
QK_BACKLIGHT_OFF = 0x7801,
QK_BACKLIGHT_TOGGLE = 0x7802,
@@ -690,9 +707,6 @@ enum qk_keycode_defines {
QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN = 0x7C1C,
QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE = 0x7C1D,
QK_SPACE_CADET_RIGHT_SHIFT_ENTER = 0x7C1E,
- QK_OUTPUT_AUTO = 0x7C20,
- QK_OUTPUT_USB = 0x7C21,
- QK_OUTPUT_BLUETOOTH = 0x7C22,
QK_UNICODE_MODE_NEXT = 0x7C30,
QK_UNICODE_MODE_PREVIOUS = 0x7C31,
QK_UNICODE_MODE_MACOS = 0x7C32,
@@ -745,6 +759,7 @@ enum qk_keycode_defines {
QK_TRI_LAYER_UPPER = 0x7C78,
QK_REPEAT_KEY = 0x7C79,
QK_ALT_REPEAT_KEY = 0x7C7A,
+ QK_LAYER_LOCK = 0x7C7B,
QK_KB_0 = 0x7E00,
QK_KB_1 = 0x7E01,
QK_KB_2 = 0x7E02,
@@ -1296,6 +1311,21 @@ enum qk_keycode_defines {
MC_29 = QK_MACRO_29,
MC_30 = QK_MACRO_30,
MC_31 = QK_MACRO_31,
+ OU_AUTO = QK_OUTPUT_AUTO,
+ OU_NEXT = QK_OUTPUT_NEXT,
+ OU_PREV = QK_OUTPUT_PREV,
+ OU_NONE = QK_OUTPUT_NONE,
+ OU_USB = QK_OUTPUT_USB,
+ OU_2P4G = QK_OUTPUT_2P4GHZ,
+ OU_BT = QK_OUTPUT_BLUETOOTH,
+ BT_NEXT = QK_BLUETOOTH_PROFILE_NEXT,
+ BT_PREV = QK_BLUETOOTH_PROFILE_PREV,
+ BT_UNPR = QK_BLUETOOTH_UNPAIR,
+ BT_PRF1 = QK_BLUETOOTH_PROFILE1,
+ BT_PRF2 = QK_BLUETOOTH_PROFILE2,
+ BT_PRF3 = QK_BLUETOOTH_PROFILE3,
+ BT_PRF4 = QK_BLUETOOTH_PROFILE4,
+ BT_PRF5 = QK_BLUETOOTH_PROFILE5,
BL_ON = QK_BACKLIGHT_ON,
BL_OFF = QK_BACKLIGHT_OFF,
BL_TOGG = QK_BACKLIGHT_TOGGLE,
@@ -1365,9 +1395,6 @@ enum qk_keycode_defines {
SC_LAPO = QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN,
SC_RAPC = QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE,
SC_SENT = QK_SPACE_CADET_RIGHT_SHIFT_ENTER,
- OU_AUTO = QK_OUTPUT_AUTO,
- OU_USB = QK_OUTPUT_USB,
- OU_BT = QK_OUTPUT_BLUETOOTH,
UC_NEXT = QK_UNICODE_MODE_NEXT,
UC_PREV = QK_UNICODE_MODE_PREVIOUS,
UC_MAC = QK_UNICODE_MODE_MACOS,
@@ -1419,6 +1446,7 @@ enum qk_keycode_defines {
TL_UPPR = QK_TRI_LAYER_UPPER,
QK_REP = QK_REPEAT_KEY,
QK_AREP = QK_ALT_REPEAT_KEY,
+ QK_LLCK = QK_LAYER_LOCK,
};
// Range Helpers
@@ -1444,6 +1472,7 @@ enum qk_keycode_defines {
#define IS_QK_AUDIO(code) ((code) >= QK_AUDIO && (code) <= QK_AUDIO_MAX)
#define IS_QK_STENO(code) ((code) >= QK_STENO && (code) <= QK_STENO_MAX)
#define IS_QK_MACRO(code) ((code) >= QK_MACRO && (code) <= QK_MACRO_MAX)
+#define IS_QK_CONNECTION(code) ((code) >= QK_CONNECTION && (code) <= QK_CONNECTION_MAX)
#define IS_QK_LIGHTING(code) ((code) >= QK_LIGHTING && (code) <= QK_LIGHTING_MAX)
#define IS_QK_QUANTUM(code) ((code) >= QK_QUANTUM && (code) <= QK_QUANTUM_MAX)
#define IS_QK_KB(code) ((code) >= QK_KB && (code) <= QK_KB_MAX)
@@ -1468,12 +1497,13 @@ enum qk_keycode_defines {
#define IS_AUDIO_KEYCODE(code) ((code) >= QK_AUDIO_ON && (code) <= QK_AUDIO_VOICE_PREVIOUS)
#define IS_STENO_KEYCODE(code) ((code) >= QK_STENO_BOLT && (code) <= QK_STENO_COMB_MAX)
#define IS_MACRO_KEYCODE(code) ((code) >= QK_MACRO_0 && (code) <= QK_MACRO_31)
+#define IS_CONNECTION_KEYCODE(code) ((code) >= QK_OUTPUT_AUTO && (code) <= QK_BLUETOOTH_PROFILE5)
#define IS_BACKLIGHT_KEYCODE(code) ((code) >= QK_BACKLIGHT_ON && (code) <= QK_BACKLIGHT_TOGGLE_BREATHING)
#define IS_LED_MATRIX_KEYCODE(code) ((code) >= QK_LED_MATRIX_ON && (code) <= QK_LED_MATRIX_SPEED_DOWN)
#define IS_UNDERGLOW_KEYCODE(code) ((code) >= QK_UNDERGLOW_TOGGLE && (code) <= QK_UNDERGLOW_SPEED_DOWN)
#define IS_RGB_KEYCODE(code) ((code) >= RGB_MODE_PLAIN && (code) <= RGB_MODE_TWINKLE)
#define IS_RGB_MATRIX_KEYCODE(code) ((code) >= QK_RGB_MATRIX_ON && (code) <= QK_RGB_MATRIX_SPEED_DOWN)
-#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_ALT_REPEAT_KEY)
+#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_LAYER_LOCK)
#define IS_KB_KEYCODE(code) ((code) >= QK_KB_0 && (code) <= QK_KB_31)
#define IS_USER_KEYCODE(code) ((code) >= QK_USER_0 && (code) <= QK_USER_31)
@@ -1493,11 +1523,12 @@ enum qk_keycode_defines {
#define AUDIO_KEYCODE_RANGE QK_AUDIO_ON ... QK_AUDIO_VOICE_PREVIOUS
#define STENO_KEYCODE_RANGE QK_STENO_BOLT ... QK_STENO_COMB_MAX
#define MACRO_KEYCODE_RANGE QK_MACRO_0 ... QK_MACRO_31
+#define CONNECTION_KEYCODE_RANGE QK_OUTPUT_AUTO ... QK_BLUETOOTH_PROFILE5
#define BACKLIGHT_KEYCODE_RANGE QK_BACKLIGHT_ON ... QK_BACKLIGHT_TOGGLE_BREATHING
#define LED_MATRIX_KEYCODE_RANGE QK_LED_MATRIX_ON ... QK_LED_MATRIX_SPEED_DOWN
#define UNDERGLOW_KEYCODE_RANGE QK_UNDERGLOW_TOGGLE ... QK_UNDERGLOW_SPEED_DOWN
#define RGB_KEYCODE_RANGE RGB_MODE_PLAIN ... RGB_MODE_TWINKLE
#define RGB_MATRIX_KEYCODE_RANGE QK_RGB_MATRIX_ON ... QK_RGB_MATRIX_SPEED_DOWN
-#define QUANTUM_KEYCODE_RANGE QK_BOOTLOADER ... QK_ALT_REPEAT_KEY
+#define QUANTUM_KEYCODE_RANGE QK_BOOTLOADER ... QK_LAYER_LOCK
#define KB_KEYCODE_RANGE QK_KB_0 ... QK_KB_31
#define USER_KEYCODE_RANGE QK_USER_0 ... QK_USER_31
diff --git a/quantum/layer_lock.c b/quantum/layer_lock.c
new file mode 100644
index 0000000000..9fc84bcfca
--- /dev/null
+++ b/quantum/layer_lock.c
@@ -0,0 +1,100 @@
+// Copyright 2022-2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "layer_lock.h"
+#include "quantum_keycodes.h"
+
+#ifndef NO_ACTION_LAYER
+// The current lock state. The kth bit is on if layer k is locked.
+layer_state_t locked_layers = 0;
+
+// Layer Lock timer to disable layer lock after X seconds inactivity
+# if defined(LAYER_LOCK_IDLE_TIMEOUT) && LAYER_LOCK_IDLE_TIMEOUT > 0
+uint32_t layer_lock_timer = 0;
+
+void layer_lock_timeout_task(void) {
+ if (locked_layers && timer_elapsed32(layer_lock_timer) > LAYER_LOCK_IDLE_TIMEOUT) {
+ layer_lock_all_off();
+ layer_lock_timer = timer_read32();
+ }
+}
+void layer_lock_activity_trigger(void) {
+ layer_lock_timer = timer_read32();
+}
+# else
+void layer_lock_timeout_task(void) {}
+void layer_lock_activity_trigger(void) {}
+# endif // LAYER_LOCK_IDLE_TIMEOUT > 0
+
+bool is_layer_locked(uint8_t layer) {
+ return locked_layers & ((layer_state_t)1 << layer);
+}
+
+void layer_lock_invert(uint8_t layer) {
+ const layer_state_t mask = (layer_state_t)1 << layer;
+ if ((locked_layers & mask) == 0) { // Layer is being locked.
+# ifndef NO_ACTION_ONESHOT
+ if (layer == get_oneshot_layer()) {
+ reset_oneshot_layer(); // Reset so that OSL doesn't turn layer off.
+ }
+# endif // NO_ACTION_ONESHOT
+ layer_on(layer);
+ layer_lock_activity_trigger();
+ } else { // Layer is being unlocked.
+ layer_off(layer);
+ }
+ layer_lock_set_kb(locked_layers ^= mask);
+}
+
+// Implement layer_lock_on/off by deferring to layer_lock_invert.
+void layer_lock_on(uint8_t layer) {
+ if (!is_layer_locked(layer)) {
+ layer_lock_invert(layer);
+ }
+}
+
+void layer_lock_off(uint8_t layer) {
+ if (is_layer_locked(layer)) {
+ layer_lock_invert(layer);
+ }
+}
+
+void layer_lock_all_off(void) {
+ layer_and(~locked_layers);
+ locked_layers = 0;
+ layer_lock_set_kb(locked_layers);
+}
+
+#else // NO_ACTION_LAYER
+bool is_layer_locked(uint8_t layer) {
+ return false;
+}
+void layer_lock_on(uint8_t layer) {}
+void layer_lock_off(uint8_t layer) {}
+void layer_lock_all_off(void) {}
+void layer_lock_invert(uint8_t layer) {}
+void layer_lock_timeout_task(void) {}
+void layer_lock_activity_trigger(void) {}
+#endif // NO_ACTION_LAYER
+
+__attribute__((weak)) bool layer_lock_set_kb(layer_state_t locked_layers) {
+ return layer_lock_set_user(locked_layers);
+}
+__attribute__((weak)) bool layer_lock_set_user(layer_state_t locked_layers) {
+ return true;
+}
+
+void layer_lock_task(void) {
+ layer_lock_timeout_task();
+}
diff --git a/quantum/layer_lock.h b/quantum/layer_lock.h
new file mode 100644
index 0000000000..97f6c60d70
--- /dev/null
+++ b/quantum/layer_lock.h
@@ -0,0 +1,98 @@
+// Copyright 2022-2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @file layer_lock.h
+ * @brief Layer Lock, a key to stay in the current layer.
+ *
+ * Overview
+ * --------
+ *
+ * Layers are often accessed by holding a button, e.g. with a momentary layer
+ * switch `MO(layer)` or layer tap `LT(layer, key)` key. But you may sometimes
+ * want to "lock" or "toggle" the layer so that it stays on without having to
+ * hold down a button. One way to do that is with a tap-toggle `TT` layer key,
+ * but here is an alternative.
+ *
+ * This library implements a "Layer Lock key". When tapped, it "locks" the
+ * highest layer to stay active, assuming the layer was activated by one of the
+ * following keys:
+ *
+ * * `MO(layer)` momentary layer switch
+ * * `LT(layer, key)` layer tap
+ * * `OSL(layer)` one-shot layer
+ * * `TT(layer)` layer tap toggle
+ * * `LM(layer, mod)` layer-mod key (the layer is locked, but not the mods)
+ *
+ * Tapping the Layer Lock key again unlocks and turns off the layer.
+ *
+ * @note When a layer is "locked", other layer keys such as `TO(layer)` or
+ * manually calling `layer_off(layer)` will override and unlock the layer.
+ *
+ * Configuration
+ * -------------
+ *
+ * Optionally, a timeout may be defined so that Layer Lock disables
+ * automatically if not keys are pressed for `LAYER_LOCK_IDLE_TIMEOUT`
+ * milliseconds. Define `LAYER_LOCK_IDLE_TIMEOUT` in your config.h, for instance
+ *
+ * #define LAYER_LOCK_IDLE_TIMEOUT 60000 // Turn off after 60 seconds.
+ *
+ * For full documentation, see
+ * <https://getreuer.info/posts/keyboards/layer-lock>
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "action_layer.h"
+#include "action_util.h"
+
+/** Returns true if `layer` is currently locked. */
+bool is_layer_locked(uint8_t layer);
+
+/** Locks and turns on `layer`. */
+void layer_lock_on(uint8_t layer);
+
+/** Unlocks and turns off `layer`. */
+void layer_lock_off(uint8_t layer);
+
+/** Unlocks and turns off all locked layers. */
+void layer_lock_all_off(void);
+
+/** Toggles whether `layer` is locked. */
+void layer_lock_invert(uint8_t layer);
+
+/**
+ * Optional callback that gets called when a layer is locked or unlocked.
+ *
+ * This is useful to represent the current lock state, e.g. by setting an LED or
+ * playing a sound. In your keymap, define
+ *
+ * void layer_lock_set_user(layer_state_t locked_layers) {
+ * // Do something like `set_led(is_layer_locked(NAV));`
+ * }
+ *
+ * @param locked_layers Bitfield in which the kth bit represents whether the
+ * kth layer is on.
+ */
+bool layer_lock_set_kb(layer_state_t locked_layers);
+bool layer_lock_set_user(layer_state_t locked_layers);
+
+/** Handle various background tasks */
+void layer_lock_task(void);
+
+/** Update any configured timeouts */
+void layer_lock_activity_trigger(void);
diff --git a/quantum/led_matrix/animations/breathing_anim.h b/quantum/led_matrix/animations/breathing_anim.h
index 0bd4cb0cc3..3d1b0d95d2 100644
--- a/quantum/led_matrix/animations/breathing_anim.h
+++ b/quantum/led_matrix/animations/breathing_anim.h
@@ -2,17 +2,12 @@
LED_MATRIX_EFFECT(BREATHING)
# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
-bool BREATHING(effect_params_t* params) {
- LED_MATRIX_USE_LIMITS(led_min, led_max);
+static uint8_t BREATHING_math(uint8_t val, uint8_t i, uint8_t time) {
+ return scale8(abs8(sin8(time / 2) - 128) * 2, val);
+}
- uint8_t val = led_matrix_eeconfig.val;
- uint16_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 8);
- val = scale8(abs8(sin8(time) - 128) * 2, val);
- for (uint8_t i = led_min; i < led_max; i++) {
- LED_MATRIX_TEST_LED_FLAGS();
- led_matrix_set_value(i, val);
- }
- return led_matrix_check_finished_leds(led_max);
+bool BREATHING(effect_params_t* params) {
+ return effect_runner_i(params, &BREATHING_math);
}
# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c
index 798ab9a120..58263c62e3 100644
--- a/quantum/led_matrix/led_matrix.c
+++ b/quantum/led_matrix/led_matrix.c
@@ -139,11 +139,20 @@ void led_matrix_update_pwm_buffers(void) {
led_matrix_driver.flush();
}
+__attribute__((weak)) int led_matrix_led_index(int index) {
+#if defined(LED_MATRIX_SPLIT)
+ if (!is_keyboard_left() && index >= k_led_matrix_split[0]) {
+ return index - k_led_matrix_split[0];
+ }
+#endif
+ return index;
+}
+
void led_matrix_set_value(int index, uint8_t value) {
#ifdef USE_CIE1931_CURVE
value = pgm_read_byte(&CIE1931_CURVE[value]);
#endif
- led_matrix_driver.set_value(index, value);
+ led_matrix_driver.set_value(led_matrix_led_index(index), value);
}
void led_matrix_set_value_all(uint8_t value) {
@@ -387,7 +396,6 @@ struct led_matrix_limits_t led_matrix_get_limits(uint8_t iter) {
limits.led_min_index = LED_MATRIX_LED_PROCESS_LIMIT * (iter);
limits.led_max_index = limits.led_min_index + LED_MATRIX_LED_PROCESS_LIMIT;
if (limits.led_max_index > LED_MATRIX_LED_COUNT) limits.led_max_index = LED_MATRIX_LED_COUNT;
- uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;
if (is_keyboard_left() && (limits.led_max_index > k_led_matrix_split[0])) limits.led_max_index = k_led_matrix_split[0];
if (!(is_keyboard_left()) && (limits.led_min_index < k_led_matrix_split[0])) limits.led_min_index = k_led_matrix_split[0];
# else
@@ -397,9 +405,8 @@ struct led_matrix_limits_t led_matrix_get_limits(uint8_t iter) {
# endif
#else
# if defined(LED_MATRIX_SPLIT)
- limits.led_min_index = 0;
- limits.led_max_index = LED_MATRIX_LED_COUNT;
- const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;
+ limits.led_min_index = 0;
+ limits.led_max_index = LED_MATRIX_LED_COUNT;
if (is_keyboard_left() && (limits.led_max_index > k_led_matrix_split[0])) limits.led_max_index = k_led_matrix_split[0];
if (!(is_keyboard_left()) && (limits.led_min_index < k_led_matrix_split[0])) limits.led_min_index = k_led_matrix_split[0];
# else
diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h
index 9a13c3e52b..a3468a2003 100644
--- a/quantum/led_matrix/led_matrix.h
+++ b/quantum/led_matrix/led_matrix.h
@@ -121,6 +121,8 @@ void eeconfig_debug_led_matrix(void);
uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
+int led_matrix_led_index(int index);
+
void led_matrix_set_value(int index, uint8_t value);
void led_matrix_set_value_all(uint8_t value);
diff --git a/quantum/logging/debug.h b/quantum/logging/debug.h
index d0590474c0..b0d9b9a10e 100644
--- a/quantum/logging/debug.h
+++ b/quantum/logging/debug.h
@@ -17,10 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
-#ifndef PROTOCOL_ARM_ATSAM
-# include <stdio.h>
-#endif
-
+#include <stdio.h>
#include <stdbool.h>
#include "print.h"
diff --git a/quantum/os_detection.c b/quantum/os_detection.c
index 96b026e247..0dd048a8c4 100644
--- a/quantum/os_detection.c
+++ b/quantum/os_detection.c
@@ -34,7 +34,7 @@ static uint16_t usb_setups[STORED_USB_SETUPS];
#endif
#ifndef OS_DETECTION_DEBOUNCE
-# define OS_DETECTION_DEBOUNCE 200
+# define OS_DETECTION_DEBOUNCE 250
#endif
// 2s should always be more than enough (otherwise, you may have other issues)
@@ -59,25 +59,40 @@ struct setups_data_t setups_data = {
};
static volatile os_variant_t detected_os = OS_UNSURE;
-static os_variant_t reported_os = OS_UNSURE;
+static volatile os_variant_t reported_os = OS_UNSURE;
// we need to be able to report OS_UNSURE if that is the stable result of the guesses
-static bool first_report = true;
+static volatile bool first_report = true;
// to react on USB state changes
-static volatile enum usb_device_state current_usb_device_state = USB_DEVICE_STATE_INIT;
-static enum usb_device_state reported_usb_device_state = USB_DEVICE_STATE_INIT;
+static volatile struct usb_device_state current_usb_device_state = {.configure_state = USB_DEVICE_STATE_NO_INIT};
+static volatile struct usb_device_state maxprev_usb_device_state = {.configure_state = USB_DEVICE_STATE_NO_INIT};
// the OS detection might be unstable for a while, "debounce" it
static volatile bool debouncing = false;
-static volatile fast_timer_t last_time;
+static volatile fast_timer_t last_time = 0;
void os_detection_task(void) {
- if (current_usb_device_state == USB_DEVICE_STATE_CONFIGURED) {
+#ifdef OS_DETECTION_KEYBOARD_RESET
+ // resetting the keyboard on the USB device state change callback results in instability, so delegate that to this task
+ // only take action if it's been stable at least once, to avoid issues with some KVMs
+ if (current_usb_device_state.configure_state <= USB_DEVICE_STATE_INIT && maxprev_usb_device_state.configure_state >= USB_DEVICE_STATE_CONFIGURED) {
+ if (debouncing && timer_elapsed_fast(last_time) >= OS_DETECTION_DEBOUNCE) {
+ soft_reset_keyboard();
+ }
+ return;
+ }
+#endif
+#ifdef OS_DETECTION_SINGLE_REPORT
+ if (!first_report) {
+ return;
+ }
+#endif
+ if (current_usb_device_state.configure_state == USB_DEVICE_STATE_CONFIGURED) {
// debouncing goes for both the detected OS as well as the USB state
if (debouncing && timer_elapsed_fast(last_time) >= OS_DETECTION_DEBOUNCE) {
- debouncing = false;
- reported_usb_device_state = current_usb_device_state;
+ debouncing = false;
+ last_time = 0;
if (detected_os != reported_os || first_report) {
first_report = false;
reported_os = detected_os;
@@ -85,13 +100,6 @@ void os_detection_task(void) {
}
}
}
-#ifdef OS_DETECTION_KEYBOARD_RESET
- // resetting the keyboard on the USB device state change callback results in instability, so delegate that to this task
- // only take action if it's been stable at least once, to avoid issues with some KVMs
- else if (current_usb_device_state == USB_DEVICE_STATE_INIT && reported_usb_device_state != USB_DEVICE_STATE_INIT) {
- soft_reset_keyboard();
- }
-#endif
}
__attribute__((weak)) bool process_detected_host_os_kb(os_variant_t detected_os) {
@@ -155,16 +163,20 @@ os_variant_t detected_host_os(void) {
void erase_wlength_data(void) {
memset(&setups_data, 0, sizeof(setups_data));
- detected_os = OS_UNSURE;
- reported_os = OS_UNSURE;
- current_usb_device_state = USB_DEVICE_STATE_INIT;
- reported_usb_device_state = USB_DEVICE_STATE_INIT;
- debouncing = false;
- first_report = true;
+ detected_os = OS_UNSURE;
+ reported_os = OS_UNSURE;
+ current_usb_device_state.configure_state = USB_DEVICE_STATE_NO_INIT;
+ maxprev_usb_device_state.configure_state = USB_DEVICE_STATE_NO_INIT;
+ debouncing = false;
+ last_time = 0;
+ first_report = true;
}
-void os_detection_notify_usb_device_state_change(enum usb_device_state usb_device_state) {
+void os_detection_notify_usb_device_state_change(struct usb_device_state usb_device_state) {
// treat this like any other source of instability
+ if (maxprev_usb_device_state.configure_state < current_usb_device_state.configure_state) {
+ maxprev_usb_device_state.configure_state = current_usb_device_state.configure_state;
+ }
current_usb_device_state = usb_device_state;
last_time = timer_read_fast();
debouncing = true;
diff --git a/quantum/os_detection.h b/quantum/os_detection.h
index b8cd898335..98a8e805e4 100644
--- a/quantum/os_detection.h
+++ b/quantum/os_detection.h
@@ -31,7 +31,7 @@ typedef enum {
void process_wlength(const uint16_t w_length);
os_variant_t detected_host_os(void);
void erase_wlength_data(void);
-void os_detection_notify_usb_device_state_change(enum usb_device_state usb_device_state);
+void os_detection_notify_usb_device_state_change(struct usb_device_state usb_device_state);
void os_detection_task(void);
diff --git a/quantum/os_detection/tests/os_detection.cpp b/quantum/os_detection/tests/os_detection.cpp
index a9f671156b..ea43de144c 100644
--- a/quantum/os_detection/tests/os_detection.cpp
+++ b/quantum/os_detection/tests/os_detection.cpp
@@ -253,9 +253,11 @@ TEST_F(OsDetectionTest, TestDoNotReportIfUsbUnstable) {
EXPECT_EQ(detected_host_os(), OS_LINUX);
}
+static struct usb_device_state usb_device_state_configured = {.configure_state = USB_DEVICE_STATE_CONFIGURED};
+
TEST_F(OsDetectionTest, TestReportAfterDebounce) {
EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX);
- os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+ os_detection_notify_usb_device_state_change(usb_device_state_configured);
os_detection_task();
assert_not_reported();
@@ -291,7 +293,7 @@ TEST_F(OsDetectionTest, TestReportAfterDebounce) {
TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) {
EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS);
- os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+ os_detection_notify_usb_device_state_change(usb_device_state_configured);
os_detection_task();
assert_not_reported();
@@ -318,7 +320,7 @@ TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) {
TEST_F(OsDetectionTest, TestReportUnsure) {
EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE);
- os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+ os_detection_notify_usb_device_state_change(usb_device_state_configured);
os_detection_task();
assert_not_reported();
@@ -345,7 +347,7 @@ TEST_F(OsDetectionTest, TestReportUnsure) {
TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE);
- os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+ os_detection_notify_usb_device_state_change(usb_device_state_configured);
os_detection_task();
assert_not_reported();
@@ -356,7 +358,7 @@ TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
// at this stage, the final result has not been reached yet
EXPECT_EQ(check_sequence({0xFF}), OS_LINUX);
- os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+ os_detection_notify_usb_device_state_change(usb_device_state_configured);
advance_time(OS_DETECTION_DEBOUNCE - 1);
os_detection_task();
assert_not_reported();
@@ -365,7 +367,7 @@ TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
// the remainder is processed
EXPECT_EQ(check_sequence({0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS);
- os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED);
+ os_detection_notify_usb_device_state_change(usb_device_state_configured);
advance_time(OS_DETECTION_DEBOUNCE - 1);
os_detection_task();
assert_not_reported();
diff --git a/quantum/painter/qp.h b/quantum/painter/qp.h
index 820c418f43..3dc77b42cf 100644
--- a/quantum/painter/qp.h
+++ b/quantum/painter/qp.h
@@ -557,6 +557,12 @@ int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, pai
# define SH1106_NUM_DEVICES 0
#endif // QUANTUM_PAINTER_SH1106_ENABLE
+#ifdef QUANTUM_PAINTER_LD7032_ENABLE
+# include "qp_ld7032.h"
+#else // QUANTUM_PAINTER_LD7032_ENABLE
+# define LD7032_NUM_DEVICES 0
+#endif // QUANTUM_PAINTER_LD7032_ENABLE
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Quantum Painter Extras
diff --git a/quantum/painter/qp_internal.c b/quantum/painter/qp_internal.c
index 7d4a6430af..5097edfa07 100644
--- a/quantum/painter/qp_internal.c
+++ b/quantum/painter/qp_internal.c
@@ -19,6 +19,7 @@ enum {
+ (GC9107_NUM_DEVICES) // GC9107
+ (SSD1351_NUM_DEVICES) // SSD1351
+ (SH1106_NUM_DEVICES) // SH1106
+ + (LD7032_NUM_DEVICES) // LD7032
};
static painter_device_t qp_devices[QP_NUM_DEVICES] = {NULL};
diff --git a/quantum/painter/rules.mk b/quantum/painter/rules.mk
index 7b2ab702ee..b773dd091c 100644
--- a/quantum/painter/rules.mk
+++ b/quantum/painter/rules.mk
@@ -17,7 +17,9 @@ VALID_QUANTUM_PAINTER_DRIVERS := \
gc9107_spi \
ssd1351_spi \
sh1106_i2c \
- sh1106_spi
+ sh1106_spi \
+ ld7032_i2c \
+ ld7032_spi
#-------------------------------------------------------------------------------
@@ -182,6 +184,29 @@ define handle_quantum_painter_driver
$(DRIVER_PATH)/painter/oled_panel/qp_oled_panel.c \
$(DRIVER_PATH)/painter/sh1106/qp_sh1106.c
+ else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ld7032_spi)
+ QUANTUM_PAINTER_NEEDS_SURFACE := yes
+ QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes
+ QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes
+ OPT_DEFS += -DQUANTUM_PAINTER_LD7032_ENABLE -DQUANTUM_PAINTER_LD7032_SPI_ENABLE
+ COMMON_VPATH += \
+ $(DRIVER_PATH)/painter/oled_panel \
+ $(DRIVER_PATH)/painter/ld7032
+ SRC += \
+ $(DRIVER_PATH)/painter/oled_panel/qp_oled_panel.c \
+ $(DRIVER_PATH)/painter/ld7032/qp_ld7032.c
+
+ else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ld7032_i2c)
+ QUANTUM_PAINTER_NEEDS_SURFACE := yes
+ QUANTUM_PAINTER_NEEDS_COMMS_I2C := yes
+ OPT_DEFS += -DQUANTUM_PAINTER_LD7032_ENABLE -DQUANTUM_PAINTER_LD7032_I2C_ENABLE
+ COMMON_VPATH += \
+ $(DRIVER_PATH)/painter/oled_panel \
+ $(DRIVER_PATH)/painter/ld7032
+ SRC += \
+ $(DRIVER_PATH)/painter/oled_panel/qp_oled_panel.c \
+ $(DRIVER_PATH)/painter/ld7032/qp_ld7032.c
+
endif
endef
diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c
index 74ce9108a9..cac2875fc8 100644
--- a/quantum/pointing_device/pointing_device.c
+++ b/quantum/pointing_device/pointing_device.c
@@ -79,7 +79,28 @@ uint16_t pointing_device_get_shared_cpi(void) {
static report_mouse_t local_mouse_report = {};
static bool pointing_device_force_send = false;
-extern const pointing_device_driver_t pointing_device_driver;
+#define POINTING_DEVICE_DRIVER_CONCAT(name) name##_pointing_device_driver
+#define POINTING_DEVICE_DRIVER(name) POINTING_DEVICE_DRIVER_CONCAT(name)
+
+#ifdef POINTING_DEVICE_DRIVER_custom
+__attribute__((weak)) void pointing_device_driver_init(void) {}
+__attribute__((weak)) report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
+ return mouse_report;
+}
+__attribute__((weak)) uint16_t pointing_device_driver_get_cpi(void) {
+ return 0;
+}
+__attribute__((weak)) void pointing_device_driver_set_cpi(uint16_t cpi) {}
+
+const pointing_device_driver_t custom_pointing_device_driver = {
+ .init = pointing_device_driver_init,
+ .get_report = pointing_device_driver_get_report,
+ .get_cpi = pointing_device_driver_get_cpi,
+ .set_cpi = pointing_device_driver_set_cpi,
+};
+#endif
+
+const pointing_device_driver_t *pointing_device_driver = &POINTING_DEVICE_DRIVER(POINTING_DEVICE_DRIVER_NAME);
/**
* @brief Keyboard level code pointing device initialisation
@@ -146,7 +167,7 @@ __attribute__((weak)) void pointing_device_init(void) {
if ((POINTING_DEVICE_THIS_SIDE))
#endif
{
- pointing_device_driver.init();
+ pointing_device_driver->init();
#ifdef POINTING_DEVICE_MOTION_PIN
# ifdef POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW
gpio_set_pin_input_high(POINTING_DEVICE_MOTION_PIN);
@@ -258,15 +279,15 @@ __attribute__((weak)) bool pointing_device_task(void) {
# if defined(POINTING_DEVICE_COMBINED)
static uint8_t old_buttons = 0;
local_mouse_report.buttons = old_buttons;
- local_mouse_report = pointing_device_driver.get_report(local_mouse_report);
+ local_mouse_report = pointing_device_driver->get_report(local_mouse_report);
old_buttons = local_mouse_report.buttons;
# elif defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT)
- local_mouse_report = POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_report(local_mouse_report) : shared_mouse_report;
+ local_mouse_report = POINTING_DEVICE_THIS_SIDE ? pointing_device_driver->get_report(local_mouse_report) : shared_mouse_report;
# else
# error "You need to define the side(s) the pointing device is on. POINTING_DEVICE_COMBINED / POINTING_DEVICE_LEFT / POINTING_DEVICE_RIGHT"
# endif
#else
- local_mouse_report = pointing_device_driver.get_report(local_mouse_report);
+ local_mouse_report = pointing_device_driver->get_report(local_mouse_report);
#endif // defined(SPLIT_POINTING_ENABLE)
#ifdef POINTING_DEVICE_MOTION_PIN
@@ -331,9 +352,9 @@ void pointing_device_set_report(report_mouse_t mouse_report) {
*/
uint16_t pointing_device_get_cpi(void) {
#if defined(SPLIT_POINTING_ENABLE)
- return POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_cpi() : shared_cpi;
+ return POINTING_DEVICE_THIS_SIDE ? pointing_device_driver->get_cpi() : shared_cpi;
#else
- return pointing_device_driver.get_cpi();
+ return pointing_device_driver->get_cpi();
#endif
}
@@ -347,12 +368,12 @@ uint16_t pointing_device_get_cpi(void) {
void pointing_device_set_cpi(uint16_t cpi) {
#if defined(SPLIT_POINTING_ENABLE)
if (POINTING_DEVICE_THIS_SIDE) {
- pointing_device_driver.set_cpi(cpi);
+ pointing_device_driver->set_cpi(cpi);
} else {
shared_cpi = cpi;
}
#else
- pointing_device_driver.set_cpi(cpi);
+ pointing_device_driver->set_cpi(cpi);
#endif
}
@@ -370,35 +391,35 @@ void pointing_device_set_cpi(uint16_t cpi) {
void pointing_device_set_cpi_on_side(bool left, uint16_t cpi) {
bool local = (is_keyboard_left() == left);
if (local) {
- pointing_device_driver.set_cpi(cpi);
+ pointing_device_driver->set_cpi(cpi);
} else {
shared_cpi = cpi;
}
}
/**
- * @brief clamps int16_t to int8_t
+ * @brief clamps int16_t to int8_t, or int32_t to int16_t
*
- * @param[in] int16_t value
- * @return int8_t clamped value
+ * @param[in] hv_clamp_range_t value
+ * @return mouse_hv_report_t clamped value
*/
-static inline int8_t pointing_device_hv_clamp(int16_t value) {
- if (value < INT8_MIN) {
- return INT8_MIN;
- } else if (value > INT8_MAX) {
- return INT8_MAX;
+static inline mouse_hv_report_t pointing_device_hv_clamp(hv_clamp_range_t value) {
+ if (value < HV_REPORT_MIN) {
+ return HV_REPORT_MIN;
+ } else if (value > HV_REPORT_MAX) {
+ return HV_REPORT_MAX;
} else {
return value;
}
}
/**
- * @brief clamps int16_t to int8_t
+ * @brief clamps int16_t to int8_t, or int32_t to int16_t
*
- * @param[in] clamp_range_t value
+ * @param[in] xy_clamp_range_t value
* @return mouse_xy_report_t clamped value
*/
-static inline mouse_xy_report_t pointing_device_xy_clamp(clamp_range_t value) {
+static inline mouse_xy_report_t pointing_device_xy_clamp(xy_clamp_range_t value) {
if (value < XY_REPORT_MIN) {
return XY_REPORT_MIN;
} else if (value > XY_REPORT_MAX) {
@@ -419,10 +440,10 @@ static inline mouse_xy_report_t pointing_device_xy_clamp(clamp_range_t value) {
* @return combined report_mouse_t of left_report and right_report
*/
report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report) {
- left_report.x = pointing_device_xy_clamp((clamp_range_t)left_report.x + right_report.x);
- left_report.y = pointing_device_xy_clamp((clamp_range_t)left_report.y + right_report.y);
- left_report.h = pointing_device_hv_clamp((int16_t)left_report.h + right_report.h);
- left_report.v = pointing_device_hv_clamp((int16_t)left_report.v + right_report.v);
+ left_report.x = pointing_device_xy_clamp((xy_clamp_range_t)left_report.x + right_report.x);
+ left_report.y = pointing_device_xy_clamp((xy_clamp_range_t)left_report.y + right_report.y);
+ left_report.h = pointing_device_hv_clamp((hv_clamp_range_t)left_report.h + right_report.h);
+ left_report.v = pointing_device_hv_clamp((hv_clamp_range_t)left_report.v + right_report.v);
left_report.buttons |= right_report.buttons;
return left_report;
}
diff --git a/quantum/pointing_device/pointing_device.h b/quantum/pointing_device/pointing_device.h
index 1cd4b0b5e6..72188c977d 100644
--- a/quantum/pointing_device/pointing_device.h
+++ b/quantum/pointing_device/pointing_device.h
@@ -21,6 +21,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "host.h"
#include "report.h"
+typedef struct {
+ void (*init)(void);
+ report_mouse_t (*get_report)(report_mouse_t mouse_report);
+ void (*set_cpi)(uint16_t);
+ uint16_t (*get_cpi)(void);
+} pointing_device_driver_t;
+
#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
# include "pointing_device_auto_mouse.h"
#endif
@@ -44,7 +51,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "drivers/sensors/azoteq_iqs5xx.h"
#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c) || defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
# include "drivers/sensors/cirque_pinnacle.h"
-# include "drivers/sensors/cirque_pinnacle_gestures.h"
# include "pointing_device_gestures.h"
#elif defined(POINTING_DEVICE_DRIVER_paw3204)
# include "drivers/sensors/paw3204.h"
@@ -74,13 +80,6 @@ uint16_t pointing_device_driver_get_cpi(void);
void pointing_device_driver_set_cpi(uint16_t cpi);
#endif
-typedef struct {
- void (*init)(void);
- report_mouse_t (*get_report)(report_mouse_t mouse_report);
- void (*set_cpi)(uint16_t);
- uint16_t (*get_cpi)(void);
-} pointing_device_driver_t;
-
typedef enum {
POINTING_DEVICE_BUTTON1,
POINTING_DEVICE_BUTTON2,
@@ -95,13 +94,26 @@ typedef enum {
#ifdef MOUSE_EXTENDED_REPORT
# define XY_REPORT_MIN INT16_MIN
# define XY_REPORT_MAX INT16_MAX
-typedef int32_t clamp_range_t;
+typedef int32_t xy_clamp_range_t;
#else
# define XY_REPORT_MIN INT8_MIN
# define XY_REPORT_MAX INT8_MAX
-typedef int16_t clamp_range_t;
+typedef int16_t xy_clamp_range_t;
#endif
+#ifdef WHEEL_EXTENDED_REPORT
+# define HV_REPORT_MIN INT16_MIN
+# define HV_REPORT_MAX INT16_MAX
+typedef int32_t hv_clamp_range_t;
+#else
+# define HV_REPORT_MIN INT8_MIN
+# define HV_REPORT_MAX INT8_MAX
+typedef int16_t hv_clamp_range_t;
+#endif
+
+#define CONSTRAIN_HID(amt) ((amt) < INT8_MIN ? INT8_MIN : ((amt) > INT8_MAX ? INT8_MAX : (amt)))
+#define CONSTRAIN_HID_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt)))
+
void pointing_device_init(void);
bool pointing_device_task(void);
bool pointing_device_send(void);
diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c
deleted file mode 100644
index bf131c6eda..0000000000
--- a/quantum/pointing_device/pointing_device_drivers.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/* Copyright 2017 Joshua Broekhuijsen <[email protected]>
- * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <[email protected]>
- * Copyright 2021 Dasky (@daskygit)
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "pointing_device.h"
-#include "pointing_device_internal.h"
-#include "debug.h"
-#include "wait.h"
-#include "timer.h"
-#include <stddef.h>
-
-#define CONSTRAIN_HID(amt) ((amt) < INT8_MIN ? INT8_MIN : ((amt) > INT8_MAX ? INT8_MAX : (amt)))
-#define CONSTRAIN_HID_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt)))
-
-// get_report functions should probably be moved to their respective drivers.
-
-#if defined(POINTING_DEVICE_DRIVER_adns5050)
-report_mouse_t adns5050_get_report(report_mouse_t mouse_report) {
- report_adns5050_t data = adns5050_read_burst();
-
- if (data.dx != 0 || data.dy != 0) {
- pd_dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy);
- mouse_report.x = (mouse_xy_report_t)data.dx;
- mouse_report.y = (mouse_xy_report_t)data.dy;
- }
-
- return mouse_report;
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = adns5050_init,
- .get_report = adns5050_get_report,
- .set_cpi = adns5050_set_cpi,
- .get_cpi = adns5050_get_cpi,
-};
-// clang-format on
-
-#elif defined(POINTING_DEVICE_DRIVER_pmw3320)
-report_mouse_t pmw3320_get_report(report_mouse_t mouse_report) {
- report_pmw3320_t data = pmw3320_read_burst();
-
- if (data.dx != 0 || data.dy != 0) {
- pd_dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy);
- mouse_report.x = (mouse_xy_report_t)data.dx;
- mouse_report.y = (mouse_xy_report_t)data.dy;
- }
-
- return mouse_report;
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = pmw3320_init,
- .get_report = pmw3320_get_report,
- .set_cpi = pmw3320_set_cpi,
- .get_cpi = pmw3320_get_cpi,
-};
-// clang-format on
-
-#elif defined(POINTING_DEVICE_DRIVER_adns9800)
-
-report_mouse_t adns9800_get_report_driver(report_mouse_t mouse_report) {
- report_adns9800_t sensor_report = adns9800_get_report();
-
- mouse_report.x = CONSTRAIN_HID_XY(sensor_report.x);
- mouse_report.y = CONSTRAIN_HID_XY(sensor_report.y);
-
- return mouse_report;
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = adns9800_init,
- .get_report = adns9800_get_report_driver,
- .set_cpi = adns9800_set_cpi,
- .get_cpi = adns9800_get_cpi
-};
-// clang-format on
-
-#elif defined(POINTING_DEVICE_DRIVER_analog_joystick)
-report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report) {
- report_analog_joystick_t data = analog_joystick_read();
-
- pd_dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y);
-
- mouse_report.x = data.x;
- mouse_report.y = data.y;
-
- mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, data.button, POINTING_DEVICE_BUTTON1);
-
- return mouse_report;
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = analog_joystick_init,
- .get_report = analog_joystick_get_report,
- .set_cpi = NULL,
- .get_cpi = NULL
-};
-// clang-format on
-
-#elif defined(POINTING_DEVICE_DRIVER_azoteq_iqs5xx)
-
-static i2c_status_t azoteq_iqs5xx_init_status = 1;
-
-void azoteq_iqs5xx_init(void) {
- i2c_init();
- azoteq_iqs5xx_wake();
- azoteq_iqs5xx_reset_suspend(true, false, true);
- wait_ms(100);
- azoteq_iqs5xx_wake();
- if (azoteq_iqs5xx_get_product() != AZOTEQ_IQS5XX_UNKNOWN) {
- azoteq_iqs5xx_setup_resolution();
- azoteq_iqs5xx_init_status = azoteq_iqs5xx_set_report_rate(AZOTEQ_IQS5XX_REPORT_RATE, AZOTEQ_IQS5XX_ACTIVE, false);
- azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_event_mode(false, false);
- azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_reati(true, false);
-# if defined(AZOTEQ_IQS5XX_ROTATION_90)
- azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(false, true, true, true, false);
-# elif defined(AZOTEQ_IQS5XX_ROTATION_180)
- azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(true, true, false, true, false);
-# elif defined(AZOTEQ_IQS5XX_ROTATION_270)
- azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(true, false, true, true, false);
-# else
- azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_xy_config(false, false, false, true, false);
-# endif
- azoteq_iqs5xx_init_status |= azoteq_iqs5xx_set_gesture_config(true);
- wait_ms(AZOTEQ_IQS5XX_REPORT_RATE + 1);
- }
-};
-
-report_mouse_t azoteq_iqs5xx_get_report(report_mouse_t mouse_report) {
- report_mouse_t temp_report = {0};
- static uint8_t previous_button_state = 0;
- static uint8_t read_error_count = 0;
-
- if (azoteq_iqs5xx_init_status == I2C_STATUS_SUCCESS) {
- azoteq_iqs5xx_base_data_t base_data = {0};
-# if !defined(POINTING_DEVICE_MOTION_PIN)
- azoteq_iqs5xx_wake();
-# endif
- i2c_status_t status = azoteq_iqs5xx_get_base_data(&base_data);
- bool ignore_movement = false;
-
- if (status == I2C_STATUS_SUCCESS) {
- // pd_dprintf("IQS5XX - previous cycle time: %d \n", base_data.previous_cycle_time);
- read_error_count = 0;
- if (base_data.gesture_events_0.single_tap || base_data.gesture_events_0.press_and_hold) {
- pd_dprintf("IQS5XX - Single tap/hold.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON1);
- } else if (base_data.gesture_events_1.two_finger_tap) {
- pd_dprintf("IQS5XX - Two finger tap.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON2);
- } else if (base_data.gesture_events_0.swipe_x_neg) {
- pd_dprintf("IQS5XX - X-.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON4);
- ignore_movement = true;
- } else if (base_data.gesture_events_0.swipe_x_pos) {
- pd_dprintf("IQS5XX - X+.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON5);
- ignore_movement = true;
- } else if (base_data.gesture_events_0.swipe_y_neg) {
- pd_dprintf("IQS5XX - Y-.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON6);
- ignore_movement = true;
- } else if (base_data.gesture_events_0.swipe_y_pos) {
- pd_dprintf("IQS5XX - Y+.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON3);
- ignore_movement = true;
- } else if (base_data.gesture_events_1.zoom) {
- if (AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l) < 0) {
- pd_dprintf("IQS5XX - Zoom out.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON7);
- } else if (AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l) > 0) {
- pd_dprintf("IQS5XX - Zoom in.\n");
- temp_report.buttons = pointing_device_handle_buttons(temp_report.buttons, true, POINTING_DEVICE_BUTTON8);
- }
- } else if (base_data.gesture_events_1.scroll) {
- pd_dprintf("IQS5XX - Scroll.\n");
- temp_report.h = CONSTRAIN_HID(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l));
- temp_report.v = CONSTRAIN_HID(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
- }
- if (base_data.number_of_fingers == 1 && !ignore_movement) {
- temp_report.x = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.x.h, base_data.x.l));
- temp_report.y = CONSTRAIN_HID_XY(AZOTEQ_IQS5XX_COMBINE_H_L_BYTES(base_data.y.h, base_data.y.l));
- }
-
- previous_button_state = temp_report.buttons;
-
- } else {
- if (read_error_count > 10) {
- read_error_count = 0;
- previous_button_state = 0;
- } else {
- read_error_count++;
- }
- temp_report.buttons = previous_button_state;
- pd_dprintf("IQS5XX - get report failed: %d \n", status);
- }
- } else {
- pd_dprintf("IQS5XX - Init failed: %d \n", azoteq_iqs5xx_init_status);
- }
-
- return temp_report;
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = azoteq_iqs5xx_init,
- .get_report = azoteq_iqs5xx_get_report,
- .set_cpi = azoteq_iqs5xx_set_cpi,
- .get_cpi = azoteq_iqs5xx_get_cpi
-};
-// clang-format on
-
-#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c) || defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
-# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
-static bool cursor_glide_enable = true;
-
-static cursor_glide_context_t glide = {.config = {
- .coef = 102, /* Good default friction coef */
- .interval = 10, /* 100sps */
- .trigger_px = 10, /* Default threshold in case of hover, set to 0 if you'd like */
- }};
-
-void cirque_pinnacle_enable_cursor_glide(bool enable) {
- cursor_glide_enable = enable;
-}
-
-void cirque_pinnacle_configure_cursor_glide(float trigger_px) {
- glide.config.trigger_px = trigger_px;
-}
-# endif
-
-# if CIRQUE_PINNACLE_POSITION_MODE
-
-# ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
-static bool is_touch_down;
-
-bool auto_mouse_activation(report_mouse_t mouse_report) {
- return is_touch_down || mouse_report.x != 0 || mouse_report.y != 0 || mouse_report.h != 0 || mouse_report.v != 0 || mouse_report.buttons;
-}
-# endif
-
-report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {
- uint16_t scale = cirque_pinnacle_get_scale();
- pinnacle_data_t touchData = cirque_pinnacle_read_data();
- mouse_xy_report_t report_x = 0, report_y = 0;
- static uint16_t x = 0, y = 0, last_scale = 0;
-
-# if defined(CIRQUE_PINNACLE_TAP_ENABLE)
- mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1);
-# endif
-# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
- cursor_glide_t glide_report = {0};
-
- if (cursor_glide_enable) {
- glide_report = cursor_glide_check(&glide);
- }
-# endif
-
- if (!touchData.valid) {
-# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
- if (cursor_glide_enable && glide_report.valid) {
- report_x = glide_report.dx;
- report_y = glide_report.dy;
- goto mouse_report_update;
- }
-# endif
- return mouse_report;
- }
-
- if (touchData.touchDown) {
- pd_dprintf("cirque_pinnacle touchData x=%4d y=%4d z=%2d\n", touchData.xValue, touchData.yValue, touchData.zValue);
- }
-
-# ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
- is_touch_down = touchData.touchDown;
-# endif
-
- // Scale coordinates to arbitrary X, Y resolution
- cirque_pinnacle_scale_data(&touchData, scale, scale);
-
- if (!cirque_pinnacle_gestures(&mouse_report, touchData)) {
- if (last_scale && scale == last_scale && x && y && touchData.xValue && touchData.yValue) {
- report_x = CONSTRAIN_HID_XY((int16_t)(touchData.xValue - x));
- report_y = CONSTRAIN_HID_XY((int16_t)(touchData.yValue - y));
- }
- x = touchData.xValue;
- y = touchData.yValue;
- last_scale = scale;
-
-# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
- if (cursor_glide_enable) {
- if (touchData.touchDown) {
- cursor_glide_update(&glide, report_x, report_y, touchData.zValue);
- } else if (!glide_report.valid) {
- glide_report = cursor_glide_start(&glide);
- if (glide_report.valid) {
- report_x = glide_report.dx;
- report_y = glide_report.dy;
- }
- }
- }
-# endif
- }
-
-# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
-mouse_report_update:
-# endif
- mouse_report.x = report_x;
- mouse_report.y = report_y;
-
- return mouse_report;
-}
-
-uint16_t cirque_pinnacle_get_cpi(void) {
- return CIRQUE_PINNACLE_PX_TO_INCH(cirque_pinnacle_get_scale());
-}
-void cirque_pinnacle_set_cpi(uint16_t cpi) {
- cirque_pinnacle_set_scale(CIRQUE_PINNACLE_INCH_TO_PX(cpi));
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = cirque_pinnacle_init,
- .get_report = cirque_pinnacle_get_report,
- .set_cpi = cirque_pinnacle_set_cpi,
- .get_cpi = cirque_pinnacle_get_cpi
-};
-// clang-format on
-# else
-report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) {
- pinnacle_data_t touchData = cirque_pinnacle_read_data();
-
- // Scale coordinates to arbitrary X, Y resolution
- cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale());
-
- if (touchData.valid) {
- mouse_report.buttons = touchData.buttons;
- mouse_report.x = CONSTRAIN_HID_XY(touchData.xDelta);
- mouse_report.y = CONSTRAIN_HID_XY(touchData.yDelta);
- mouse_report.v = touchData.wheelCount;
- }
- return mouse_report;
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = cirque_pinnacle_init,
- .get_report = cirque_pinnacle_get_report,
- .set_cpi = cirque_pinnacle_set_scale,
- .get_cpi = cirque_pinnacle_get_scale
-};
-// clang-format on
-# endif
-
-#elif defined(POINTING_DEVICE_DRIVER_paw3204)
-
-report_mouse_t paw3204_get_report(report_mouse_t mouse_report) {
- report_paw3204_t data = paw3204_read();
- if (data.isMotion) {
- pd_dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y);
-
- mouse_report.x = data.x;
- mouse_report.y = data.y;
- }
-
- return mouse_report;
-}
-const pointing_device_driver_t pointing_device_driver = {
- .init = paw3204_init,
- .get_report = paw3204_get_report,
- .set_cpi = paw3204_set_cpi,
- .get_cpi = paw3204_get_cpi,
-};
-#elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball)
-
-mouse_xy_report_t pimoroni_trackball_adapt_values(clamp_range_t* offset) {
- if (*offset > XY_REPORT_MAX) {
- *offset -= XY_REPORT_MAX;
- return (mouse_xy_report_t)XY_REPORT_MAX;
- } else if (*offset < XY_REPORT_MIN) {
- *offset += XY_REPORT_MAX;
- return (mouse_xy_report_t)XY_REPORT_MIN;
- } else {
- mouse_xy_report_t temp_return = *offset;
- *offset = 0;
- return temp_return;
- }
-}
-
-report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report) {
- static uint16_t debounce = 0;
- static uint8_t error_count = 0;
- pimoroni_data_t pimoroni_data = {0};
- static clamp_range_t x_offset = 0, y_offset = 0;
-
- if (error_count < PIMORONI_TRACKBALL_ERROR_COUNT) {
- i2c_status_t status = read_pimoroni_trackball(&pimoroni_data);
-
- if (status == I2C_STATUS_SUCCESS) {
- error_count = 0;
-
- if (!(pimoroni_data.click & 128)) {
- mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1);
- if (!debounce) {
- x_offset += pimoroni_trackball_get_offsets(pimoroni_data.right, pimoroni_data.left, PIMORONI_TRACKBALL_SCALE);
- y_offset += pimoroni_trackball_get_offsets(pimoroni_data.down, pimoroni_data.up, PIMORONI_TRACKBALL_SCALE);
- mouse_report.x = pimoroni_trackball_adapt_values(&x_offset);
- mouse_report.y = pimoroni_trackball_adapt_values(&y_offset);
- } else {
- debounce--;
- }
- } else {
- mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, true, POINTING_DEVICE_BUTTON1);
- debounce = PIMORONI_TRACKBALL_DEBOUNCE_CYCLES;
- }
- } else {
- error_count++;
- }
- }
- return mouse_report;
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = pimoroni_trackball_device_init,
- .get_report = pimoroni_trackball_get_report,
- .set_cpi = pimoroni_trackball_set_cpi,
- .get_cpi = pimoroni_trackball_get_cpi
-};
-// clang-format on
-
-#elif defined(POINTING_DEVICE_DRIVER_pmw3360) || defined(POINTING_DEVICE_DRIVER_pmw3389)
-static void pmw33xx_init_wrapper(void) {
- pmw33xx_init(0);
-}
-
-static void pmw33xx_set_cpi_wrapper(uint16_t cpi) {
- pmw33xx_set_cpi(0, cpi);
-}
-
-static uint16_t pmw33xx_get_cpi_wrapper(void) {
- return pmw33xx_get_cpi(0);
-}
-
-report_mouse_t pmw33xx_get_report(report_mouse_t mouse_report) {
- pmw33xx_report_t report = pmw33xx_read_burst(0);
- static bool in_motion = false;
-
- if (report.motion.b.is_lifted) {
- return mouse_report;
- }
-
- if (!report.motion.b.is_motion) {
- in_motion = false;
- return mouse_report;
- }
-
- if (!in_motion) {
- in_motion = true;
- pd_dprintf("PWM3360 (0): starting motion\n");
- }
-
- mouse_report.x = CONSTRAIN_HID_XY(report.delta_x);
- mouse_report.y = CONSTRAIN_HID_XY(report.delta_y);
- return mouse_report;
-}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = pmw33xx_init_wrapper,
- .get_report = pmw33xx_get_report,
- .set_cpi = pmw33xx_set_cpi_wrapper,
- .get_cpi = pmw33xx_get_cpi_wrapper
-};
-// clang-format on
-
-#else
-__attribute__((weak)) void pointing_device_driver_init(void) {}
-__attribute__((weak)) report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
- return mouse_report;
-}
-__attribute__((weak)) uint16_t pointing_device_driver_get_cpi(void) {
- return 0;
-}
-__attribute__((weak)) void pointing_device_driver_set_cpi(uint16_t cpi) {}
-
-// clang-format off
-const pointing_device_driver_t pointing_device_driver = {
- .init = pointing_device_driver_init,
- .get_report = pointing_device_driver_get_report,
- .get_cpi = pointing_device_driver_get_cpi,
- .set_cpi = pointing_device_driver_set_cpi
-};
-// clang-format on
-
-#endif
diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c
index b0034d136a..c99a66a74b 100644
--- a/quantum/process_keycode/process_combo.c
+++ b/quantum/process_keycode/process_combo.c
@@ -36,19 +36,19 @@ __attribute__((weak)) uint8_t combo_ref_from_layer(uint8_t layer) {
#endif
#ifdef COMBO_MUST_HOLD_PER_COMBO
-__attribute__((weak)) bool get_combo_must_hold(uint16_t index, combo_t *combo) {
+__attribute__((weak)) bool get_combo_must_hold(uint16_t combo_index, combo_t *combo) {
return false;
}
#endif
#ifdef COMBO_MUST_TAP_PER_COMBO
-__attribute__((weak)) bool get_combo_must_tap(uint16_t index, combo_t *combo) {
+__attribute__((weak)) bool get_combo_must_tap(uint16_t combo_index, combo_t *combo) {
return false;
}
#endif
#ifdef COMBO_TERM_PER_COMBO
-__attribute__((weak)) uint16_t get_combo_term(uint16_t index, combo_t *combo) {
+__attribute__((weak)) uint16_t get_combo_term(uint16_t combo_index, combo_t *combo) {
return COMBO_TERM;
}
#endif
@@ -65,12 +65,20 @@ __attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo
}
#endif
+#ifdef COMBO_PROCESS_KEY_REPRESS
+__attribute__((weak)) bool process_combo_key_repress(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) {
+ return false;
+}
+#endif
+
#ifdef COMBO_SHOULD_TRIGGER
__attribute__((weak)) bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) {
return true;
}
#endif
+typedef enum { COMBO_KEY_NOT_PRESSED, COMBO_KEY_PRESSED, COMBO_KEY_REPRESSED } combo_key_action_t;
+
#ifndef COMBO_NO_TIMER
static uint16_t timer = 0;
#endif
@@ -414,14 +422,14 @@ static bool keys_pressed_in_order(uint16_t combo_index, combo_t *combo, uint16_t
}
#endif
-static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) {
+static combo_key_action_t process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) {
uint8_t key_count = 0;
uint16_t key_index = -1;
_find_key_index_and_count(combo->keys, keycode, &key_index, &key_count);
/* Continue processing if key isn't part of current combo. */
if (-1 == (int16_t)key_index) {
- return false;
+ return COMBO_KEY_NOT_PRESSED;
}
bool key_is_part_of_combo = (!COMBO_DISABLED(combo) && is_combo_enabled()
@@ -449,7 +457,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
/* Don't buffer this combo if its combo term has passed. */
if (timer && timer_elapsed(timer) > time) {
DISABLE_COMBO(combo);
- return true;
+ return COMBO_KEY_PRESSED;
} else
#endif
{
@@ -485,6 +493,15 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
}
} // if timer elapsed end
}
+#ifdef COMBO_PROCESS_KEY_REPRESS
+ } else if (record->event.pressed) {
+ if (COMBO_ACTIVE(combo)) {
+ if (process_combo_key_repress(combo_index, combo, key_index, keycode)) {
+ KEY_STATE_DOWN(combo->state, key_index);
+ return COMBO_KEY_REPRESSED;
+ }
+ }
+#endif
} else {
// chord releases
if (!COMBO_ACTIVE(combo) && ALL_COMBO_KEYS_ARE_DOWN(COMBO_STATE(combo), key_count)) {
@@ -531,12 +548,12 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
KEY_STATE_UP(combo->state, key_index);
}
- return key_is_part_of_combo;
+ return key_is_part_of_combo ? COMBO_KEY_PRESSED : COMBO_KEY_NOT_PRESSED;
}
bool process_combo(uint16_t keycode, keyrecord_t *record) {
- bool is_combo_key = false;
- bool no_combo_keys_pressed = true;
+ uint8_t is_combo_key = COMBO_KEY_NOT_PRESSED;
+ bool no_combo_keys_pressed = true;
if (keycode == QK_COMBO_ON && record->event.pressed) {
combo_enable();
@@ -582,12 +599,17 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) {
# endif
#endif
- if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) {
- key_buffer[key_buffer_size++] = (queued_record_t){
- .record = *record,
- .keycode = keycode,
- .combo_index = -1, // this will be set when applying combos
- };
+#ifdef COMBO_PROCESS_KEY_REPRESS
+ if (is_combo_key == COMBO_KEY_PRESSED)
+#endif
+ {
+ if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) {
+ key_buffer[key_buffer_size++] = (queued_record_t){
+ .record = *record,
+ .keycode = keycode,
+ .combo_index = -1, // this will be set when applying combos
+ };
+ }
}
} else {
if (combo_buffer_read != combo_buffer_write) {
diff --git a/quantum/process_keycode/process_connection.c b/quantum/process_keycode/process_connection.c
new file mode 100644
index 0000000000..b0e230d680
--- /dev/null
+++ b/quantum/process_keycode/process_connection.c
@@ -0,0 +1,36 @@
+// Copyright 2024 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "outputselect.h"
+#include "process_connection.h"
+
+bool process_connection(uint16_t keycode, keyrecord_t *record) {
+ if (record->event.pressed) {
+ switch (keycode) {
+ case QK_OUTPUT_NEXT:
+ set_output(OUTPUT_AUTO); // This should cycle through the outputs going forward. Ensure `docs/keycodes.md`, `docs/features/bluetooth.md` are updated when it does.
+ return false;
+ case QK_OUTPUT_USB:
+ set_output(OUTPUT_USB);
+ return false;
+ case QK_OUTPUT_BLUETOOTH:
+ set_output(OUTPUT_BLUETOOTH);
+ return false;
+
+ case QK_OUTPUT_PREV:
+ case QK_OUTPUT_NONE:
+ case QK_OUTPUT_2P4GHZ:
+ case QK_BLUETOOTH_PROFILE_NEXT:
+ case QK_BLUETOOTH_PROFILE_PREV:
+ case QK_BLUETOOTH_UNPAIR:
+ case QK_BLUETOOTH_PROFILE1:
+ case QK_BLUETOOTH_PROFILE2:
+ case QK_BLUETOOTH_PROFILE3:
+ case QK_BLUETOOTH_PROFILE4:
+ case QK_BLUETOOTH_PROFILE5:
+ // As-yet unimplemented.
+ // When implementation is done, ensure `docs/keycodes.md`, `docs/features/bluetooth.md` are updated accordingly.
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/quantum/process_keycode/process_connection.h b/quantum/process_keycode/process_connection.h
new file mode 100644
index 0000000000..cc58011bb7
--- /dev/null
+++ b/quantum/process_keycode/process_connection.h
@@ -0,0 +1,9 @@
+// Copyright 2024 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "action.h"
+
+bool process_connection(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/process_keycode/process_haptic.c b/quantum/process_keycode/process_haptic.c
index 21d4c5ce30..54cd7b817e 100644
--- a/quantum/process_keycode/process_haptic.c
+++ b/quantum/process_keycode/process_haptic.c
@@ -129,7 +129,7 @@ bool process_haptic(uint16_t keycode, keyrecord_t *record) {
}
}
- if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) {
+ if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED))) {
if (record->event.pressed) {
// keypress
if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) {
diff --git a/quantum/process_keycode/process_layer_lock.c b/quantum/process_keycode/process_layer_lock.c
new file mode 100644
index 0000000000..6946d3c886
--- /dev/null
+++ b/quantum/process_keycode/process_layer_lock.c
@@ -0,0 +1,82 @@
+// Copyright 2022-2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "layer_lock.h"
+#include "process_layer_lock.h"
+#include "quantum_keycodes.h"
+#include "action_util.h"
+
+// The current lock state. The kth bit is on if layer k is locked.
+extern layer_state_t locked_layers;
+
+// Handles an event on an `MO` or `TT` layer switch key.
+static inline bool handle_mo_or_tt(uint8_t layer, keyrecord_t* record) {
+ if (is_layer_locked(layer)) {
+ if (record->event.pressed) { // On press, unlock the layer.
+ layer_lock_invert(layer);
+ }
+ return false; // Skip default handling.
+ }
+ return true;
+}
+
+bool process_layer_lock(uint16_t keycode, keyrecord_t* record) {
+#ifndef NO_ACTION_LAYER
+ layer_lock_activity_trigger();
+
+ // The intention is that locked layers remain on. If something outside of
+ // this feature turned any locked layers off, unlock them.
+ if ((locked_layers & ~layer_state) != 0) {
+ layer_lock_set_kb(locked_layers &= layer_state);
+ }
+
+ if (keycode == QK_LAYER_LOCK) {
+ if (record->event.pressed) { // The layer lock key was pressed.
+ layer_lock_invert(get_highest_layer(layer_state));
+ }
+ return false;
+ }
+
+ switch (keycode) {
+ case QK_MOMENTARY ... QK_MOMENTARY_MAX: // `MO(layer)` keys.
+ return handle_mo_or_tt(QK_MOMENTARY_GET_LAYER(keycode), record);
+
+ case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: // `TT(layer)`.
+ return handle_mo_or_tt(QK_LAYER_TAP_TOGGLE_GET_LAYER(keycode), record);
+
+ case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: { // `LM(layer, mod)`.
+ uint8_t layer = QK_LAYER_MOD_GET_LAYER(keycode);
+ if (is_layer_locked(layer)) {
+ if (record->event.pressed) { // On press, unlock the layer.
+ layer_lock_invert(layer);
+ } else { // On release, clear the mods.
+ clear_mods();
+ send_keyboard_report();
+ }
+ return false; // Skip default handling.
+ }
+ } break;
+
+# ifndef NO_ACTION_TAPPING
+ case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: // `LT(layer, key)` keys.
+ if (record->tap.count == 0 && !record->event.pressed && is_layer_locked(QK_LAYER_TAP_GET_LAYER(keycode))) {
+ // Release event on a held layer-tap key where the layer is locked.
+ return false; // Skip default handling so that layer stays on.
+ }
+ break;
+# endif // NO_ACTION_TAPPING
+ }
+#endif // NO_ACTION_LAYER
+ return true;
+}
diff --git a/quantum/process_keycode/process_layer_lock.h b/quantum/process_keycode/process_layer_lock.h
new file mode 100644
index 0000000000..6795110029
--- /dev/null
+++ b/quantum/process_keycode/process_layer_lock.h
@@ -0,0 +1,21 @@
+// Copyright 2022-2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "action.h"
+
+bool process_layer_lock(uint16_t keycode, keyrecord_t* record);
diff --git a/quantum/process_keycode/process_rgb.c b/quantum/process_keycode/process_rgb.c
deleted file mode 100644
index b113d1c1e7..0000000000
--- a/quantum/process_keycode/process_rgb.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright 2019
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-#include "process_rgb.h"
-#include "action_util.h"
-
-#ifdef RGB_MATRIX_ENABLE
-# include "rgb_matrix.h"
-#endif
-#ifdef RGBLIGHT_ENABLE
-# include "rgblight.h"
-#endif
-
-typedef void (*rgb_func_pointer)(void);
-
-/**
- * Wrapper for inc/dec rgb keycode
- *
- * noinline to optimise for firmware size not speed (not in hot path)
- */
-#if (defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)) || (defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES))
-static void __attribute__((noinline)) handleKeycodeRGB(const uint8_t is_shifted, const rgb_func_pointer inc_func, const rgb_func_pointer dec_func) {
- if (is_shifted) {
- dec_func();
- } else {
- inc_func();
- }
-}
-#endif
-
-/**
- * Wrapper for animation mode
- * - if not in animation family -> jump to that animation
- * - otherwise -> wrap round animation speed
- *
- * noinline to optimise for firmware size not speed (not in hot path)
- */
-static void __attribute__((noinline, unused)) handleKeycodeRGBMode(const uint8_t start, const uint8_t end) {
- if ((start <= rgblight_get_mode()) && (rgblight_get_mode() < end)) {
- rgblight_step();
- } else {
- rgblight_mode(start);
- }
-}
-
-/**
- * Handle keycodes for both rgblight and rgbmatrix
- */
-bool process_rgb(const uint16_t keycode, const keyrecord_t *record) {
- // need to trigger on key-up for edge-case issue
-#ifndef RGB_TRIGGER_ON_KEYDOWN
- if (!record->event.pressed) {
-#else
- if (record->event.pressed) {
-#endif
-#if (defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)) || (defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES))
- uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
-#endif
- switch (keycode) {
- case QK_UNDERGLOW_TOGGLE:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- rgblight_toggle();
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- rgb_matrix_toggle();
-#endif
- return false;
- case QK_UNDERGLOW_MODE_NEXT:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_step, rgblight_step_reverse);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_step, rgb_matrix_step_reverse);
-#endif
- return false;
- case QK_UNDERGLOW_MODE_PREVIOUS:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_step_reverse, rgblight_step);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_step_reverse, rgb_matrix_step);
-#endif
- return false;
- case QK_UNDERGLOW_HUE_UP:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_increase_hue, rgblight_decrease_hue);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_increase_hue, rgb_matrix_decrease_hue);
-#endif
- return false;
- case QK_UNDERGLOW_HUE_DOWN:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_decrease_hue, rgblight_increase_hue);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_decrease_hue, rgb_matrix_increase_hue);
-#endif
- return false;
- case QK_UNDERGLOW_SATURATION_UP:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_increase_sat, rgblight_decrease_sat);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_increase_sat, rgb_matrix_decrease_sat);
-#endif
- return false;
- case QK_UNDERGLOW_SATURATION_DOWN:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_decrease_sat, rgblight_increase_sat);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_decrease_sat, rgb_matrix_increase_sat);
-#endif
- return false;
- case QK_UNDERGLOW_VALUE_UP:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_increase_val, rgblight_decrease_val);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_increase_val, rgb_matrix_decrease_val);
-#endif
- return false;
- case QK_UNDERGLOW_VALUE_DOWN:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_decrease_val, rgblight_increase_val);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_decrease_val, rgb_matrix_increase_val);
-#endif
- return false;
- case QK_UNDERGLOW_SPEED_UP:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_increase_speed, rgblight_decrease_speed);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_increase_speed, rgb_matrix_decrease_speed);
-#endif
- return false;
- case QK_UNDERGLOW_SPEED_DOWN:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgblight_decrease_speed, rgblight_increase_speed);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- handleKeycodeRGB(shifted, rgb_matrix_decrease_speed, rgb_matrix_increase_speed);
-#endif
- return false;
- case RGB_MODE_PLAIN:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
- rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
- rgb_matrix_mode(RGB_MATRIX_SOLID_COLOR);
-#endif
- return false;
- case RGB_MODE_BREATHE:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_BREATHING)
- handleKeycodeRGBMode(RGBLIGHT_MODE_BREATHING, RGBLIGHT_MODE_BREATHING_end);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && defined(ENABLE_RGB_MATRIX_BREATHING)
- rgb_matrix_mode(RGB_MATRIX_BREATHING);
-#endif
- return false;
- case RGB_MODE_RAINBOW:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RAINBOW_MOOD)
- handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_MOOD, RGBLIGHT_MODE_RAINBOW_MOOD_end);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && defined(ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT)
- rgb_matrix_mode(RGB_MATRIX_CYCLE_LEFT_RIGHT);
-#endif
- return false;
- case RGB_MODE_SWIRL:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL)
- handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_SWIRL, RGBLIGHT_MODE_RAINBOW_SWIRL_end);
-#endif
-#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && defined(ENABLE_RGB_MATRIX_CYCLE_PINWHEEL)
- rgb_matrix_mode(RGB_MATRIX_CYCLE_PINWHEEL);
-#endif
- return false;
- case RGB_MODE_SNAKE:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_SNAKE)
- handleKeycodeRGBMode(RGBLIGHT_MODE_SNAKE, RGBLIGHT_MODE_SNAKE_end);
-#endif
- return false;
- case RGB_MODE_KNIGHT:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_KNIGHT)
- handleKeycodeRGBMode(RGBLIGHT_MODE_KNIGHT, RGBLIGHT_MODE_KNIGHT_end);
-#endif
- return false;
- case RGB_MODE_XMAS:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_CHRISTMAS)
- rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
-#endif
- return false;
- case RGB_MODE_GRADIENT:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_STATIC_GRADIENT)
- handleKeycodeRGBMode(RGBLIGHT_MODE_STATIC_GRADIENT, RGBLIGHT_MODE_STATIC_GRADIENT_end);
-#endif
- return false;
- case RGB_MODE_RGBTEST:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RGB_TEST)
- rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
-#endif
- return false;
- case RGB_MODE_TWINKLE:
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_TWINKLE)
- handleKeycodeRGBMode(RGBLIGHT_MODE_TWINKLE, RGBLIGHT_MODE_TWINKLE_end);
-#endif
- return false;
- }
- }
-
- return true;
-}
diff --git a/quantum/process_keycode/process_rgb.h b/quantum/process_keycode/process_rgb.h
deleted file mode 100644
index b1069d4bb6..0000000000
--- a/quantum/process_keycode/process_rgb.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2019
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-#include "action.h"
-
-bool process_rgb(const uint16_t keycode, const keyrecord_t *record);
diff --git a/quantum/process_keycode/process_underglow.c b/quantum/process_keycode/process_underglow.c
index 779672ac07..6104cd02c6 100644
--- a/quantum/process_keycode/process_underglow.c
+++ b/quantum/process_keycode/process_underglow.c
@@ -2,87 +2,200 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "process_underglow.h"
-#include "rgblight.h"
+#if defined(RGBLIGHT_ENABLE)
+# include "rgblight.h"
+#endif
#include "action_util.h"
#include "keycodes.h"
#include "modifiers.h"
+// TODO: Remove this
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+# include "rgb_matrix.h"
+#endif
+
bool process_underglow(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
switch (keycode) {
case QK_UNDERGLOW_TOGGLE:
+#if defined(RGBLIGHT_ENABLE)
rgblight_toggle();
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ rgb_matrix_toggle();
+#endif
return false;
case QK_UNDERGLOW_MODE_NEXT:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_step_reverse();
} else {
rgblight_step();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_step_reverse();
+ } else {
+ rgb_matrix_step();
+ }
+#endif
return false;
case QK_UNDERGLOW_MODE_PREVIOUS:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_step();
} else {
rgblight_step_reverse();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_step();
+ } else {
+ rgb_matrix_step_reverse();
+ }
+#endif
return false;
case QK_UNDERGLOW_HUE_UP:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_decrease_hue();
} else {
rgblight_increase_hue();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_decrease_hue();
+ } else {
+ rgb_matrix_increase_hue();
+ }
+#endif
return false;
case QK_UNDERGLOW_HUE_DOWN:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_increase_hue();
} else {
rgblight_decrease_hue();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_increase_hue();
+ } else {
+ rgb_matrix_decrease_hue();
+ }
+#endif
return false;
case QK_UNDERGLOW_SATURATION_UP:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_decrease_sat();
} else {
rgblight_increase_sat();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_decrease_sat();
+ } else {
+ rgb_matrix_increase_sat();
+ }
+#endif
return false;
case QK_UNDERGLOW_SATURATION_DOWN:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_increase_sat();
} else {
rgblight_decrease_sat();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_increase_sat();
+ } else {
+ rgb_matrix_decrease_sat();
+ }
+#endif
return false;
case QK_UNDERGLOW_VALUE_UP:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_decrease_val();
} else {
rgblight_increase_val();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_decrease_val();
+ } else {
+ rgb_matrix_increase_val();
+ }
+#endif
return false;
case QK_UNDERGLOW_VALUE_DOWN:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
- rgblight_increase_hue();
+ rgblight_increase_val();
} else {
- rgblight_decrease_hue();
+ rgblight_decrease_val();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_increase_val();
+ } else {
+ rgb_matrix_decrease_val();
+ }
+#endif
return false;
case QK_UNDERGLOW_SPEED_UP:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_decrease_speed();
} else {
rgblight_increase_speed();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_decrease_speed();
+ } else {
+ rgb_matrix_increase_speed();
+ }
+#endif
return false;
case QK_UNDERGLOW_SPEED_DOWN:
+#if defined(RGBLIGHT_ENABLE)
if (shifted) {
rgblight_increase_speed();
} else {
rgblight_decrease_speed();
}
+#endif
+
+#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_SHARED_KEYCODES)
+ if (shifted) {
+ rgb_matrix_increase_speed();
+ } else {
+ rgb_matrix_decrease_speed();
+ }
+#endif
return false;
}
}
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 011f9d73e4..4aef26a6a5 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -21,7 +21,7 @@
#endif
#ifdef BLUETOOTH_ENABLE
-# include "outputselect.h"
+# include "process_connection.h"
#endif
#ifdef GRAVE_ESC_ENABLE
@@ -56,8 +56,12 @@
# include "process_programmable_button.h"
#endif
+#if defined(RGB_MATRIX_ENABLE)
+# include "process_rgb_matrix.h"
+#endif
+
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
-# include "process_rgb.h"
+# include "process_underglow.h"
#endif
#ifdef SECURE_ENABLE
@@ -72,6 +76,10 @@
# include "process_unicode_common.h"
#endif
+#ifdef LAYER_LOCK_ENABLE
+# include "process_layer_lock.h"
+#endif
+
#ifdef AUDIO_ENABLE
# ifndef GOODBYE_SONG
# define GOODBYE_SONG SONG(GOODBYE_SOUND)
@@ -246,10 +254,9 @@ uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) {
/* Get keycode, and then process pre tapping functionality */
bool pre_process_record_quantum(keyrecord_t *record) {
- uint16_t keycode = get_record_keycode(record, true);
- return pre_process_record_kb(keycode, record) &&
+ return pre_process_record_kb(get_record_keycode(record, true), record) &&
#ifdef COMBO_ENABLE
- process_combo(keycode, record) &&
+ process_combo(get_record_keycode(record, true), record) &&
#endif
true;
}
@@ -380,7 +387,10 @@ bool process_record_quantum(keyrecord_t *record) {
process_grave_esc(keycode, record) &&
#endif
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
- process_rgb(keycode, record) &&
+ process_underglow(keycode, record) &&
+#endif
+#if defined(RGB_MATRIX_ENABLE)
+ process_rgb_matrix(keycode, record) &&
#endif
#ifdef JOYSTICK_ENABLE
process_joystick(keycode, record) &&
@@ -394,6 +404,12 @@ bool process_record_quantum(keyrecord_t *record) {
#ifdef TRI_LAYER_ENABLE
process_tri_layer(keycode, record) &&
#endif
+#ifdef LAYER_LOCK_ENABLE
+ process_layer_lock(keycode, record) &&
+#endif
+#ifdef BLUETOOTH_ENABLE
+ process_connection(keycode, record) &&
+#endif
true)) {
return false;
}
@@ -431,17 +447,6 @@ bool process_record_quantum(keyrecord_t *record) {
velocikey_toggle();
return false;
#endif
-#ifdef BLUETOOTH_ENABLE
- case QK_OUTPUT_AUTO:
- set_output(OUTPUT_AUTO);
- return false;
- case QK_OUTPUT_USB:
- set_output(OUTPUT_USB);
- return false;
- case QK_OUTPUT_BLUETOOTH:
- set_output(OUTPUT_BLUETOOTH);
- return false;
-#endif
#ifndef NO_ACTION_ONESHOT
case QK_ONE_SHOT_TOGGLE:
oneshot_toggle();
@@ -486,14 +491,18 @@ bool process_record_quantum(keyrecord_t *record) {
return process_action_kb(record);
}
-void set_single_persistent_default_layer(uint8_t default_layer) {
+void set_single_default_layer(uint8_t default_layer) {
#if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
PLAY_SONG(default_layer_songs[default_layer]);
#endif
- eeconfig_update_default_layer((layer_state_t)1 << default_layer);
default_layer_set((layer_state_t)1 << default_layer);
}
+void set_single_persistent_default_layer(uint8_t default_layer) {
+ eeconfig_update_default_layer((layer_state_t)1 << default_layer);
+ set_single_default_layer(default_layer);
+}
+
//------------------------------------------------------------------------------
// Override these functions in your keymap file to play different tunes on
// different events such as startup and bootloader jump
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 5446ab1ad7..9db88a54d4 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -240,6 +240,11 @@ extern layer_state_t layer_state;
# include "os_detection.h"
#endif
+#ifdef LAYER_LOCK_ENABLE
+# include "layer_lock.h"
+#endif
+
+void set_single_default_layer(uint8_t default_layer);
void set_single_persistent_default_layer(uint8_t default_layer);
#define IS_LAYER_ON(layer) layer_state_is(layer)
diff --git a/quantum/quantum_keycodes_legacy.h b/quantum/quantum_keycodes_legacy.h
index e1562077e5..21aec90675 100644
--- a/quantum/quantum_keycodes_legacy.h
+++ b/quantum/quantum_keycodes_legacy.h
@@ -55,3 +55,5 @@
#define KC_ACL1 QK_MOUSE_ACCELERATION_1
#define KC_MS_ACCEL2 QK_MOUSE_ACCELERATION_2
#define KC_ACL2 QK_MOUSE_ACCELERATION_2
+
+#define QK_OUTPUT_AUTO OU_AUTO
diff --git a/quantum/rgb_matrix/animations/alpha_mods_anim.h b/quantum/rgb_matrix/animations/alpha_mods_anim.h
index 59b8381d69..2f76feb0fc 100644
--- a/quantum/rgb_matrix/animations/alpha_mods_anim.h
+++ b/quantum/rgb_matrix/animations/alpha_mods_anim.h
@@ -6,10 +6,10 @@ RGB_MATRIX_EFFECT(ALPHAS_MODS)
bool ALPHAS_MODS(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- HSV hsv = rgb_matrix_config.hsv;
- RGB rgb1 = rgb_matrix_hsv_to_rgb(hsv);
+ hsv_t hsv = rgb_matrix_config.hsv;
+ rgb_t rgb1 = rgb_matrix_hsv_to_rgb(hsv);
hsv.h += rgb_matrix_config.speed;
- RGB rgb2 = rgb_matrix_hsv_to_rgb(hsv);
+ rgb_t rgb2 = rgb_matrix_hsv_to_rgb(hsv);
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
diff --git a/quantum/rgb_matrix/animations/breathing_anim.h b/quantum/rgb_matrix/animations/breathing_anim.h
index e9a3c96e1b..8fa8e3dad4 100644
--- a/quantum/rgb_matrix/animations/breathing_anim.h
+++ b/quantum/rgb_matrix/animations/breathing_anim.h
@@ -2,18 +2,13 @@
RGB_MATRIX_EFFECT(BREATHING)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-bool BREATHING(effect_params_t* params) {
- RGB_MATRIX_USE_LIMITS(led_min, led_max);
+hsv_t BREATHING_math(hsv_t hsv, uint8_t i, uint8_t time) {
+ hsv.v = scale8(abs8(sin8(time / 2) - 128) * 2, hsv.v);
+ return hsv;
+}
- HSV hsv = rgb_matrix_config.hsv;
- uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
- hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
- for (uint8_t i = led_min; i < led_max; i++) {
- RGB_MATRIX_TEST_LED_FLAGS();
- rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
- }
- return rgb_matrix_check_finished_leds(led_max);
+bool BREATHING(effect_params_t* params) {
+ return effect_runner_i(params, &BREATHING_math);
}
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
diff --git a/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h b/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h
index 06aa8b5ed5..5ae5b193b0 100644
--- a/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h
+++ b/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(BAND_PINWHEEL_SAT)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV BAND_PINWHEEL_SAT_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) {
+static hsv_t BAND_PINWHEEL_SAT_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t time) {
hsv.s = scale8(hsv.s - time - atan2_8(dy, dx) * 3, hsv.s);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h b/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h
index bcbc319498..157a8c1c19 100644
--- a/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h
+++ b/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(BAND_PINWHEEL_VAL)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV BAND_PINWHEEL_VAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) {
+static hsv_t BAND_PINWHEEL_VAL_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t time) {
hsv.v = scale8(hsv.v - time - atan2_8(dy, dx) * 3, hsv.v);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/colorband_sat_anim.h b/quantum/rgb_matrix/animations/colorband_sat_anim.h
index cb0897ad3e..a0d0e6e811 100644
--- a/quantum/rgb_matrix/animations/colorband_sat_anim.h
+++ b/quantum/rgb_matrix/animations/colorband_sat_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(BAND_SAT)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV BAND_SAT_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t BAND_SAT_math(hsv_t hsv, uint8_t i, uint8_t time) {
int16_t s = hsv.s - abs(scale8(g_led_config.point[i].x, 228) + 28 - time) * 8;
hsv.s = scale8(s < 0 ? 0 : s, hsv.s);
return hsv;
diff --git a/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h b/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h
index d26eb37855..7d2e5b3269 100644
--- a/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h
+++ b/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(BAND_SPIRAL_SAT)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV BAND_SPIRAL_SAT_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
+static hsv_t BAND_SPIRAL_SAT_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
hsv.s = scale8(hsv.s + dist - time - atan2_8(dy, dx), hsv.s);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h b/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h
index 3ae34bb6f0..9cd9c084d1 100644
--- a/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h
+++ b/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(BAND_SPIRAL_VAL)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV BAND_SPIRAL_VAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
+static hsv_t BAND_SPIRAL_VAL_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
hsv.v = scale8(hsv.v + dist - time - atan2_8(dy, dx), hsv.v);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/colorband_val_anim.h b/quantum/rgb_matrix/animations/colorband_val_anim.h
index 69c29f53a3..ccffae259f 100644
--- a/quantum/rgb_matrix/animations/colorband_val_anim.h
+++ b/quantum/rgb_matrix/animations/colorband_val_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(BAND_VAL)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV BAND_VAL_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t BAND_VAL_math(hsv_t hsv, uint8_t i, uint8_t time) {
int16_t v = hsv.v - abs(scale8(g_led_config.point[i].x, 228) + 28 - time) * 8;
hsv.v = scale8(v < 0 ? 0 : v, hsv.v);
return hsv;
diff --git a/quantum/rgb_matrix/animations/cycle_all_anim.h b/quantum/rgb_matrix/animations/cycle_all_anim.h
index d8c7220d95..8fafcf8d11 100644
--- a/quantum/rgb_matrix/animations/cycle_all_anim.h
+++ b/quantum/rgb_matrix/animations/cycle_all_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(CYCLE_ALL)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV CYCLE_ALL_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t CYCLE_ALL_math(hsv_t hsv, uint8_t i, uint8_t time) {
hsv.h = time;
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/cycle_left_right_anim.h b/quantum/rgb_matrix/animations/cycle_left_right_anim.h
index 84c2127aff..2d8871a300 100644
--- a/quantum/rgb_matrix/animations/cycle_left_right_anim.h
+++ b/quantum/rgb_matrix/animations/cycle_left_right_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(CYCLE_LEFT_RIGHT)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV CYCLE_LEFT_RIGHT_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t CYCLE_LEFT_RIGHT_math(hsv_t hsv, uint8_t i, uint8_t time) {
hsv.h = g_led_config.point[i].x - time;
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/cycle_out_in_anim.h b/quantum/rgb_matrix/animations/cycle_out_in_anim.h
index 9513fe9593..faf920a608 100644
--- a/quantum/rgb_matrix/animations/cycle_out_in_anim.h
+++ b/quantum/rgb_matrix/animations/cycle_out_in_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(CYCLE_OUT_IN)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV CYCLE_OUT_IN_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
+static hsv_t CYCLE_OUT_IN_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
hsv.h = 3 * dist / 2 + time;
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h b/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h
index 3cca45f27a..4203a8ffd2 100644
--- a/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h
+++ b/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(CYCLE_OUT_IN_DUAL)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV CYCLE_OUT_IN_DUAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) {
+static hsv_t CYCLE_OUT_IN_DUAL_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t time) {
dx = (k_rgb_matrix_center.x / 2) - abs8(dx);
uint8_t dist = sqrt16(dx * dx + dy * dy);
hsv.h = 3 * dist + time;
diff --git a/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h b/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h
index de5993992c..d557ffeb78 100644
--- a/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h
+++ b/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(CYCLE_PINWHEEL)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV CYCLE_PINWHEEL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) {
+static hsv_t CYCLE_PINWHEEL_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t time) {
hsv.h = atan2_8(dy, dx) + time;
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/cycle_spiral_anim.h b/quantum/rgb_matrix/animations/cycle_spiral_anim.h
index 904450179e..6d7a2dc5b4 100644
--- a/quantum/rgb_matrix/animations/cycle_spiral_anim.h
+++ b/quantum/rgb_matrix/animations/cycle_spiral_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(CYCLE_SPIRAL)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV CYCLE_SPIRAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
+static hsv_t CYCLE_SPIRAL_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
hsv.h = dist - time - atan2_8(dy, dx);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/cycle_up_down_anim.h b/quantum/rgb_matrix/animations/cycle_up_down_anim.h
index dce05fecff..09c8ace46b 100644
--- a/quantum/rgb_matrix/animations/cycle_up_down_anim.h
+++ b/quantum/rgb_matrix/animations/cycle_up_down_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(CYCLE_UP_DOWN)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV CYCLE_UP_DOWN_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t CYCLE_UP_DOWN_math(hsv_t hsv, uint8_t i, uint8_t time) {
hsv.h = g_led_config.point[i].y - time;
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/dual_beacon_anim.h b/quantum/rgb_matrix/animations/dual_beacon_anim.h
index 5585015b86..7279f1ce53 100644
--- a/quantum/rgb_matrix/animations/dual_beacon_anim.h
+++ b/quantum/rgb_matrix/animations/dual_beacon_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(DUAL_BEACON)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV DUAL_BEACON_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
+static hsv_t DUAL_BEACON_math(hsv_t hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * cos + (g_led_config.point[i].x - k_rgb_matrix_center.x) * sin) / 128;
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/flower_blooming_anim.h b/quantum/rgb_matrix/animations/flower_blooming_anim.h
index 7629fde858..91f70c8d52 100644
--- a/quantum/rgb_matrix/animations/flower_blooming_anim.h
+++ b/quantum/rgb_matrix/animations/flower_blooming_anim.h
@@ -18,7 +18,7 @@
RGB_MATRIX_EFFECT(FLOWER_BLOOMING)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-typedef HSV (*flower_blooming_f)(HSV hsv, uint8_t i, uint8_t time);
+typedef hsv_t (*flower_blooming_f)(hsv_t hsv, uint8_t i, uint8_t time);
bool effect_runner_bloom(effect_params_t* params, flower_blooming_f effect_func) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
@@ -27,17 +27,17 @@ bool effect_runner_bloom(effect_params_t* params, flower_blooming_f effect_func)
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
if (g_led_config.point[i].y > k_rgb_matrix_center.y) {
- RGB bgr = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));
+ rgb_t bgr = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));
rgb_matrix_set_color(i, bgr.b, bgr.g, bgr.r);
} else {
- RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
}
return rgb_matrix_check_finished_leds(led_max);
}
-static HSV FLOWER_BLOOMING_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t FLOWER_BLOOMING_math(hsv_t hsv, uint8_t i, uint8_t time) {
if (g_led_config.point[i].y > k_rgb_matrix_center.y)
hsv.h = g_led_config.point[i].x * 3 - g_led_config.point[i].y * 3 + time;
else
diff --git a/quantum/rgb_matrix/animations/gradient_left_right_anim.h b/quantum/rgb_matrix/animations/gradient_left_right_anim.h
index ebb06f59f2..4175ab330d 100644
--- a/quantum/rgb_matrix/animations/gradient_left_right_anim.h
+++ b/quantum/rgb_matrix/animations/gradient_left_right_anim.h
@@ -5,14 +5,14 @@ RGB_MATRIX_EFFECT(GRADIENT_LEFT_RIGHT)
bool GRADIENT_LEFT_RIGHT(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- HSV hsv = rgb_matrix_config.hsv;
+ hsv_t hsv = rgb_matrix_config.hsv;
uint8_t scale = scale8(64, rgb_matrix_config.speed);
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
// The x range will be 0..224, map this to 0..7
// Relies on hue being 8-bit and wrapping
- hsv.h = rgb_matrix_config.hsv.h + (scale * g_led_config.point[i].x >> 5);
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ hsv.h = rgb_matrix_config.hsv.h + (scale * g_led_config.point[i].x >> 5);
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return rgb_matrix_check_finished_leds(led_max);
diff --git a/quantum/rgb_matrix/animations/gradient_up_down_anim.h b/quantum/rgb_matrix/animations/gradient_up_down_anim.h
index febc3919a8..e3953fb035 100644
--- a/quantum/rgb_matrix/animations/gradient_up_down_anim.h
+++ b/quantum/rgb_matrix/animations/gradient_up_down_anim.h
@@ -5,14 +5,14 @@ RGB_MATRIX_EFFECT(GRADIENT_UP_DOWN)
bool GRADIENT_UP_DOWN(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- HSV hsv = rgb_matrix_config.hsv;
+ hsv_t hsv = rgb_matrix_config.hsv;
uint8_t scale = scale8(64, rgb_matrix_config.speed);
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
// The y range will be 0..64, map this to 0..4
// Relies on hue being 8-bit and wrapping
- hsv.h = rgb_matrix_config.hsv.h + scale * (g_led_config.point[i].y >> 4);
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ hsv.h = rgb_matrix_config.hsv.h + scale * (g_led_config.point[i].y >> 4);
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return rgb_matrix_check_finished_leds(led_max);
diff --git a/quantum/rgb_matrix/animations/hue_breathing_anim.h b/quantum/rgb_matrix/animations/hue_breathing_anim.h
index 8537762832..5316e92dbd 100644
--- a/quantum/rgb_matrix/animations/hue_breathing_anim.h
+++ b/quantum/rgb_matrix/animations/hue_breathing_anim.h
@@ -7,10 +7,10 @@ RGB_MATRIX_EFFECT(HUE_BREATHING)
bool HUE_BREATHING(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
uint8_t huedelta = 12;
- HSV hsv = rgb_matrix_config.hsv;
+ hsv_t hsv = rgb_matrix_config.hsv;
uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
hsv.h = hsv.h + scale8(abs8(sin8(time) - 128) * 2, huedelta);
- RGB rgb = hsv_to_rgb(hsv);
+ rgb_t rgb = hsv_to_rgb(hsv);
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
diff --git a/quantum/rgb_matrix/animations/hue_pendulum_anim.h b/quantum/rgb_matrix/animations/hue_pendulum_anim.h
index 7d8cbcdfb2..ba0a5b45a4 100644
--- a/quantum/rgb_matrix/animations/hue_pendulum_anim.h
+++ b/quantum/rgb_matrix/animations/hue_pendulum_anim.h
@@ -5,7 +5,7 @@ RGB_MATRIX_EFFECT(HUE_PENDULUM)
// Change huedelta to adjust range of hue change. 0-255.
// Looks better with a low value and slow speed for subtle change.
// Hue Pendulum - color changes in a wave to the right before reversing direction
-static HSV HUE_PENDULUM_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t HUE_PENDULUM_math(hsv_t hsv, uint8_t i, uint8_t time) {
uint8_t huedelta = 12;
hsv.h = hsv.h + scale8(abs8(sin8(time) + (g_led_config.point[i].x) - 128) * 2, huedelta);
return hsv;
diff --git a/quantum/rgb_matrix/animations/hue_wave_anim.h b/quantum/rgb_matrix/animations/hue_wave_anim.h
index 81aa7e139e..7b729a1816 100644
--- a/quantum/rgb_matrix/animations/hue_wave_anim.h
+++ b/quantum/rgb_matrix/animations/hue_wave_anim.h
@@ -5,7 +5,7 @@ RGB_MATRIX_EFFECT(HUE_WAVE)
// Change huedelta to adjust range of hue change. 0-255.
// Looks better with a low value and slow speed for subtle change.
// Hue Wave - color changes in a wave to the right
-static HSV HUE_WAVE_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t HUE_WAVE_math(hsv_t hsv, uint8_t i, uint8_t time) {
uint8_t huedelta = 24;
hsv.h = hsv.h + scale8(abs8(g_led_config.point[i].x - time), huedelta);
return hsv;
diff --git a/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h b/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h
index 5d3df1059e..5790b27367 100644
--- a/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h
+++ b/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h
@@ -2,25 +2,33 @@
RGB_MATRIX_EFFECT(JELLYBEAN_RAINDROPS)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static void jellybean_raindrops_set_color(int i, effect_params_t* params) {
+static void jellybean_raindrops_set_color(uint8_t i, effect_params_t* params) {
if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return;
- HSV hsv = {random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v};
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+
+ hsv_t hsv = {random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v};
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
bool JELLYBEAN_RAINDROPS(effect_params_t* params) {
+ static uint16_t index = RGB_MATRIX_LED_COUNT + 1;
+
+ // Periodic trigger for LED change
+ if ((params->iter == 0) && (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 5 == 0)) {
+ index = random8_max(RGB_MATRIX_LED_COUNT);
+ }
+
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- if (!params->init) {
- // Change one LED every tick, make sure speed is not 0
- if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 5 == 0) {
- jellybean_raindrops_set_color(random8_max(RGB_MATRIX_LED_COUNT), params);
- }
- } else {
- for (int i = led_min; i < led_max; i++) {
+ if (params->init) {
+ for (uint8_t i = led_min; i < led_max; i++) {
jellybean_raindrops_set_color(i, params);
}
}
+ // Change LED once and set index out of range till next trigger
+ else if (led_min <= index && index < led_max) {
+ jellybean_raindrops_set_color(index, params);
+ index = RGB_MATRIX_LED_COUNT + 1;
+ }
return rgb_matrix_check_finished_leds(led_max);
}
diff --git a/quantum/rgb_matrix/animations/pixel_flow_anim.h b/quantum/rgb_matrix/animations/pixel_flow_anim.h
index 27567b4f3a..35170f9588 100644
--- a/quantum/rgb_matrix/animations/pixel_flow_anim.h
+++ b/quantum/rgb_matrix/animations/pixel_flow_anim.h
@@ -7,7 +7,7 @@ RGB_MATRIX_EFFECT(PIXEL_FLOW)
static bool PIXEL_FLOW(effect_params_t* params) {
// LED state array
- static RGB led[RGB_MATRIX_LED_COUNT];
+ static rgb_t led[RGB_MATRIX_LED_COUNT];
static uint32_t wait_timer = 0;
if (wait_timer > g_rgb_timer) {
@@ -22,7 +22,7 @@ static bool PIXEL_FLOW(effect_params_t* params) {
// Clear LEDs and fill the state array
rgb_matrix_set_color_all(0, 0, 0);
for (uint8_t j = 0; j < RGB_MATRIX_LED_COUNT; ++j) {
- led[j] = (random8() & 2) ? (RGB){0, 0, 0} : hsv_to_rgb((HSV){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v});
+ led[j] = (random8() & 2) ? (rgb_t){0, 0, 0} : hsv_to_rgb((hsv_t){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v});
}
}
@@ -39,7 +39,7 @@ static bool PIXEL_FLOW(effect_params_t* params) {
led[j] = led[j + 1];
}
// Fill last LED
- led[led_max - 1] = (random8() & 2) ? (RGB){0, 0, 0} : hsv_to_rgb((HSV){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v});
+ led[led_max - 1] = (random8() & 2) ? (rgb_t){0, 0, 0} : hsv_to_rgb((hsv_t){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v});
// Set pulse timer
wait_timer = g_rgb_timer + interval();
}
diff --git a/quantum/rgb_matrix/animations/pixel_fractal_anim.h b/quantum/rgb_matrix/animations/pixel_fractal_anim.h
index 90a75ed321..bf5c22a64e 100644
--- a/quantum/rgb_matrix/animations/pixel_fractal_anim.h
+++ b/quantum/rgb_matrix/animations/pixel_fractal_anim.h
@@ -26,11 +26,11 @@ static bool PIXEL_FRACTAL(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
if (g_rgb_timer > wait_timer) {
- RGB rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv);
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv);
for (uint8_t h = 0; h < MATRIX_ROWS; ++h) {
// Light and copy columns outward
for (uint8_t l = 0; l < MID_COL - 1; ++l) {
- RGB index_rgb = led[h][l] ? (RGB){rgb.r, rgb.g, rgb.b} : (RGB){0, 0, 0};
+ rgb_t index_rgb = led[h][l] ? (rgb_t){rgb.r, rgb.g, rgb.b} : (rgb_t){0, 0, 0};
if (HAS_ANY_FLAGS(g_led_config.flags[g_led_config.matrix_co[h][l]], params->flags)) {
rgb_matrix_set_color(g_led_config.matrix_co[h][l], index_rgb.r, index_rgb.g, index_rgb.b);
}
@@ -41,7 +41,7 @@ static bool PIXEL_FRACTAL(effect_params_t* params) {
}
// Light both middle columns
- RGB index_rgb = led[h][MID_COL - 1] ? (RGB){rgb.r, rgb.g, rgb.b} : (RGB){0, 0, 0};
+ rgb_t index_rgb = led[h][MID_COL - 1] ? (rgb_t){rgb.r, rgb.g, rgb.b} : (rgb_t){0, 0, 0};
if (HAS_ANY_FLAGS(g_led_config.flags[g_led_config.matrix_co[h][MID_COL - 1]], params->flags)) {
rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL - 1], index_rgb.r, index_rgb.g, index_rgb.b);
}
diff --git a/quantum/rgb_matrix/animations/pixel_rain_anim.h b/quantum/rgb_matrix/animations/pixel_rain_anim.h
index 26cd73b578..c0370831d8 100644
--- a/quantum/rgb_matrix/animations/pixel_rain_anim.h
+++ b/quantum/rgb_matrix/animations/pixel_rain_anim.h
@@ -6,25 +6,20 @@ RGB_MATRIX_EFFECT(PIXEL_RAIN)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
static bool PIXEL_RAIN(effect_params_t* params) {
- static uint32_t wait_timer = 0;
+ static fast_timer_t timer = 0;
+ static uint16_t index = RGB_MATRIX_LED_COUNT + 1;
- inline uint32_t interval(void) {
- return 500 / scale16by8(qadd8(rgb_matrix_config.speed, 16), 16);
- }
-
- inline void rain_pixel(uint8_t led_index) {
- if (!HAS_ANY_FLAGS(g_led_config.flags[led_index], params->flags)) {
- return;
- }
- HSV hsv = (random8() & 2) ? (HSV){0, 0, 0} : (HSV){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v};
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
- rgb_matrix_set_color(led_index, rgb.r, rgb.g, rgb.b);
- wait_timer = g_rgb_timer + interval();
+ if ((params->iter == 0) && (timer_elapsed_fast(timer) > (320 - rgb_matrix_config.speed))) {
+ index = random8_max(RGB_MATRIX_LED_COUNT);
+ timer = timer_read_fast();
}
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- if (g_rgb_timer > wait_timer) {
- rain_pixel(random8_max(RGB_MATRIX_LED_COUNT));
+ if (led_min <= index && index < led_max && HAS_ANY_FLAGS(g_led_config.flags[index], params->flags)) {
+ hsv_t hsv = (random8() & 2) ? (hsv_t){0, 0, 0} : (hsv_t){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v};
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
+ rgb_matrix_set_color(index, rgb.r, rgb.g, rgb.b);
+ index = RGB_MATRIX_LED_COUNT + 1;
}
return rgb_matrix_check_finished_leds(led_max);
}
diff --git a/quantum/rgb_matrix/animations/rainbow_beacon_anim.h b/quantum/rgb_matrix/animations/rainbow_beacon_anim.h
index bdcca5530f..3c7d8e59d2 100644
--- a/quantum/rgb_matrix/animations/rainbow_beacon_anim.h
+++ b/quantum/rgb_matrix/animations/rainbow_beacon_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(RAINBOW_BEACON)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV RAINBOW_BEACON_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
+static hsv_t RAINBOW_BEACON_math(hsv_t hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 2 * cos + (g_led_config.point[i].x - k_rgb_matrix_center.x) * 2 * sin) / 128;
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h b/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h
index f7b8f6c2f3..309ea82975 100644
--- a/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h
+++ b/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(RAINBOW_MOVING_CHEVRON)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV RAINBOW_MOVING_CHEVRON_math(HSV hsv, uint8_t i, uint8_t time) {
+static hsv_t RAINBOW_MOVING_CHEVRON_math(hsv_t hsv, uint8_t i, uint8_t time) {
hsv.h += abs8(g_led_config.point[i].y - k_rgb_matrix_center.y) + (g_led_config.point[i].x - time);
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h b/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h
index 91e31ea8cc..5d2558d492 100644
--- a/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h
+++ b/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h
@@ -2,7 +2,7 @@
RGB_MATRIX_EFFECT(RAINBOW_PINWHEELS)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV RAINBOW_PINWHEELS_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
+static hsv_t RAINBOW_PINWHEELS_math(hsv_t hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 3 * cos + (56 - abs8(g_led_config.point[i].x - k_rgb_matrix_center.x)) * 3 * sin) / 128;
return hsv;
}
diff --git a/quantum/rgb_matrix/animations/raindrops_anim.h b/quantum/rgb_matrix/animations/raindrops_anim.h
index e8e1f6de04..a682156da2 100644
--- a/quantum/rgb_matrix/animations/raindrops_anim.h
+++ b/quantum/rgb_matrix/animations/raindrops_anim.h
@@ -4,7 +4,7 @@ RGB_MATRIX_EFFECT(RAINDROPS)
static void raindrops_set_color(int i, effect_params_t* params) {
if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return;
- HSV hsv = {0, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v};
+ hsv_t hsv = {0, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v};
// Take the shortest path between hues
int16_t deltaH = ((rgb_matrix_config.hsv.h + 180) % 360 - rgb_matrix_config.hsv.h) / 4;
@@ -14,8 +14,8 @@ static void raindrops_set_color(int i, effect_params_t* params) {
deltaH += 256;
}
- hsv.h = rgb_matrix_config.hsv.h + (deltaH * (random8() & 0x03));
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ hsv.h = rgb_matrix_config.hsv.h + (deltaH * (random8() & 0x03));
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
diff --git a/quantum/rgb_matrix/animations/riverflow_anim.h b/quantum/rgb_matrix/animations/riverflow_anim.h
index 195d15986d..e9ef25f70c 100644
--- a/quantum/rgb_matrix/animations/riverflow_anim.h
+++ b/quantum/rgb_matrix/animations/riverflow_anim.h
@@ -4,18 +4,14 @@ RGB_MATRIX_EFFECT(RIVERFLOW)
// inspired by @PleasureTek's Massdrop Alt LED animation
-bool RIVERFLOW(effect_params_t* params) {
- RGB_MATRIX_USE_LIMITS(led_min, led_max);
- for (uint8_t i = led_min; i < led_max; i++) {
- RGB_MATRIX_TEST_LED_FLAGS();
- HSV hsv = rgb_matrix_config.hsv;
- uint16_t time = scale16by8(g_rgb_timer + (i * 315), rgb_matrix_config.speed / 8);
- hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
- rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
- }
+hsv_t RIVERFLOW_math(hsv_t hsv, uint8_t i, uint8_t time) {
+ time = scale16by8(g_rgb_timer + (i * 315), rgb_matrix_config.speed / 8);
+ hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
+ return hsv;
+}
- return rgb_matrix_check_finished_leds(led_max);
+bool RIVERFLOW(effect_params_t* params) {
+ return effect_runner_i(params, &RIVERFLOW_math);
}
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h
index 2ad0f22c28..d43f1c0d70 100644
--- a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h
@@ -1,6 +1,6 @@
#pragma once
-typedef HSV (*dx_dy_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t time);
+typedef hsv_t (*dx_dy_f)(hsv_t hsv, int16_t dx, int16_t dy, uint8_t time);
bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
@@ -10,7 +10,7 @@ bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) {
RGB_MATRIX_TEST_LED_FLAGS();
int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x;
int16_t dy = g_led_config.point[i].y - k_rgb_matrix_center.y;
- RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, time));
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, time));
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return rgb_matrix_check_finished_leds(led_max);
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h
index bcae7c79b6..29fa42a0ed 100644
--- a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h
@@ -1,6 +1,6 @@
#pragma once
-typedef HSV (*dx_dy_dist_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time);
+typedef hsv_t (*dx_dy_dist_f)(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time);
bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
@@ -11,7 +11,7 @@ bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func)
int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x;
int16_t dy = g_led_config.point[i].y - k_rgb_matrix_center.y;
uint8_t dist = sqrt16(dx * dx + dy * dy);
- RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, dist, time));
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, dist, time));
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return rgb_matrix_check_finished_leds(led_max);
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_i.h b/quantum/rgb_matrix/animations/runners/effect_runner_i.h
index b4de2992b6..670fd83ebe 100644
--- a/quantum/rgb_matrix/animations/runners/effect_runner_i.h
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_i.h
@@ -1,6 +1,6 @@
#pragma once
-typedef HSV (*i_f)(HSV hsv, uint8_t i, uint8_t time);
+typedef hsv_t (*i_f)(hsv_t hsv, uint8_t i, uint8_t time);
bool effect_runner_i(effect_params_t* params, i_f effect_func) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
@@ -8,7 +8,7 @@ bool effect_runner_i(effect_params_t* params, i_f effect_func) {
uint8_t time = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed / 4, 1));
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
- RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return rgb_matrix_check_finished_leds(led_max);
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h b/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h
index f9584d7071..958db170ae 100644
--- a/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h
@@ -2,7 +2,7 @@
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
-typedef HSV (*reactive_f)(HSV hsv, uint16_t offset);
+typedef hsv_t (*reactive_f)(hsv_t hsv, uint16_t offset);
bool effect_runner_reactive(effect_params_t* params, reactive_f effect_func) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
@@ -20,7 +20,7 @@ bool effect_runner_reactive(effect_params_t* params, reactive_f effect_func) {
}
uint16_t offset = scale16by8(tick, qadd8(rgb_matrix_config.speed, 1));
- RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, offset));
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, offset));
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return rgb_matrix_check_finished_leds(led_max);
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h b/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h
index 41020eb47f..2e18491450 100644
--- a/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h
@@ -2,7 +2,7 @@
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
-typedef HSV (*reactive_splash_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick);
+typedef hsv_t (*reactive_splash_f)(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick);
bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, reactive_splash_f effect_func) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
@@ -10,8 +10,8 @@ bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, react
uint8_t count = g_last_hit_tracker.count;
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
- HSV hsv = rgb_matrix_config.hsv;
- hsv.v = 0;
+ hsv_t hsv = rgb_matrix_config.hsv;
+ hsv.v = 0;
for (uint8_t j = start; j < count; j++) {
int16_t dx = g_led_config.point[i].x - g_last_hit_tracker.x[j];
int16_t dy = g_led_config.point[i].y - g_last_hit_tracker.y[j];
@@ -19,8 +19,8 @@ bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, react
uint16_t tick = scale16by8(g_last_hit_tracker.tick[j], qadd8(rgb_matrix_config.speed, 1));
hsv = effect_func(hsv, dx, dy, dist, tick);
}
- hsv.v = scale8(hsv.v, rgb_matrix_config.hsv.v);
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ hsv.v = scale8(hsv.v, rgb_matrix_config.hsv.v);
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return rgb_matrix_check_finished_leds(led_max);
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h b/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h
index 7776491d51..b96530aa5f 100644
--- a/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h
@@ -1,6 +1,6 @@
#pragma once
-typedef HSV (*sin_cos_i_f)(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time);
+typedef hsv_t (*sin_cos_i_f)(hsv_t hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time);
bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
@@ -10,7 +10,7 @@ bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) {
int8_t sin_value = sin8(time) - 128;
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
- RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, cos_value, sin_value, i, time));
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, cos_value, sin_value, i, time));
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return rgb_matrix_check_finished_leds(led_max);
diff --git a/quantum/rgb_matrix/animations/solid_color_anim.h b/quantum/rgb_matrix/animations/solid_color_anim.h
index c8762dcbc2..82b0007df9 100644
--- a/quantum/rgb_matrix/animations/solid_color_anim.h
+++ b/quantum/rgb_matrix/animations/solid_color_anim.h
@@ -4,7 +4,7 @@ RGB_MATRIX_EFFECT(SOLID_COLOR)
bool SOLID_COLOR(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- RGB rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv);
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv);
for (uint8_t i = led_min; i < led_max; i++) {
RGB_MATRIX_TEST_LED_FLAGS();
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
diff --git a/quantum/rgb_matrix/animations/solid_reactive_anim.h b/quantum/rgb_matrix/animations/solid_reactive_anim.h
index e18ffb5f2b..67f568ca38 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_anim.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_anim.h
@@ -3,7 +3,7 @@
RGB_MATRIX_EFFECT(SOLID_REACTIVE)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV SOLID_REACTIVE_math(HSV hsv, uint16_t offset) {
+static hsv_t SOLID_REACTIVE_math(hsv_t hsv, uint16_t offset) {
# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4);
# endif
diff --git a/quantum/rgb_matrix/animations/solid_reactive_cross.h b/quantum/rgb_matrix/animations/solid_reactive_cross.h
index a18d6b03dd..e52a7d8481 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_cross.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_cross.h
@@ -11,7 +11,7 @@ RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTICROSS)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV SOLID_REACTIVE_CROSS_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
+static hsv_t SOLID_REACTIVE_CROSS_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
uint16_t effect = tick + dist;
dx = dx < 0 ? dx * -1 : dx;
dy = dy < 0 ? dy * -1 : dy;
diff --git a/quantum/rgb_matrix/animations/solid_reactive_nexus.h b/quantum/rgb_matrix/animations/solid_reactive_nexus.h
index 53cc008616..471a2682ca 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_nexus.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_nexus.h
@@ -11,7 +11,7 @@ RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTINEXUS)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV SOLID_REACTIVE_NEXUS_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
+static hsv_t SOLID_REACTIVE_NEXUS_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
uint16_t effect = tick - dist;
if (effect > 255) effect = 255;
if (dist > 72) effect = 255;
diff --git a/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h b/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h
index 7f4e48747a..f20f1b1fb6 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h
@@ -3,7 +3,7 @@
RGB_MATRIX_EFFECT(SOLID_REACTIVE_SIMPLE)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV SOLID_REACTIVE_SIMPLE_math(HSV hsv, uint16_t offset) {
+static hsv_t SOLID_REACTIVE_SIMPLE_math(hsv_t hsv, uint16_t offset) {
# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4);
# endif
diff --git a/quantum/rgb_matrix/animations/solid_reactive_wide.h b/quantum/rgb_matrix/animations/solid_reactive_wide.h
index feca126648..b780c13d27 100644
--- a/quantum/rgb_matrix/animations/solid_reactive_wide.h
+++ b/quantum/rgb_matrix/animations/solid_reactive_wide.h
@@ -11,7 +11,7 @@ RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTIWIDE)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static HSV SOLID_REACTIVE_WIDE_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
+static hsv_t SOLID_REACTIVE_WIDE_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
uint16_t effect = tick + dist * 5;
if (effect > 255) effect = 255;
# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
diff --git a/quantum/rgb_matrix/animations/solid_splash_anim.h b/quantum/rgb_matrix/animations/solid_splash_anim.h
index 77d6f8c5eb..839ab05b38 100644
--- a/quantum/rgb_matrix/animations/solid_splash_anim.h
+++ b/quantum/rgb_matrix/animations/solid_splash_anim.h
@@ -11,7 +11,7 @@ RGB_MATRIX_EFFECT(SOLID_MULTISPLASH)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-HSV SOLID_SPLASH_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
+hsv_t SOLID_SPLASH_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
uint16_t effect = tick - dist;
if (effect > 255) effect = 255;
hsv.v = qadd8(hsv.v, 255 - effect);
diff --git a/quantum/rgb_matrix/animations/splash_anim.h b/quantum/rgb_matrix/animations/splash_anim.h
index 06459e1b0a..a28cadb9f4 100644
--- a/quantum/rgb_matrix/animations/splash_anim.h
+++ b/quantum/rgb_matrix/animations/splash_anim.h
@@ -11,7 +11,7 @@ RGB_MATRIX_EFFECT(MULTISPLASH)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-HSV SPLASH_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
+hsv_t SPLASH_math(hsv_t hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
uint16_t effect = tick - dist;
if (effect > 255) effect = 255;
hsv.h += effect;
diff --git a/quantum/rgb_matrix/animations/starlight_anim.h b/quantum/rgb_matrix/animations/starlight_anim.h
index 91626a4663..742e843b57 100644
--- a/quantum/rgb_matrix/animations/starlight_anim.h
+++ b/quantum/rgb_matrix/animations/starlight_anim.h
@@ -4,9 +4,9 @@ RGB_MATRIX_EFFECT(STARLIGHT)
void set_starlight_color(uint8_t i, effect_params_t* params) {
uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
- HSV hsv = rgb_matrix_config.hsv;
+ hsv_t hsv = rgb_matrix_config.hsv;
hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
diff --git a/quantum/rgb_matrix/animations/starlight_dual_hue_anim.h b/quantum/rgb_matrix/animations/starlight_dual_hue_anim.h
index 5ef831476f..50ce5d6ab4 100644
--- a/quantum/rgb_matrix/animations/starlight_dual_hue_anim.h
+++ b/quantum/rgb_matrix/animations/starlight_dual_hue_anim.h
@@ -4,10 +4,10 @@ RGB_MATRIX_EFFECT(STARLIGHT_DUAL_HUE)
void set_starlight_dual_hue_color(uint8_t i, effect_params_t* params) {
uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
- HSV hsv = rgb_matrix_config.hsv;
+ hsv_t hsv = rgb_matrix_config.hsv;
hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
hsv.h = hsv.h + random8_max((30 + 1 - -30) + -30);
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
diff --git a/quantum/rgb_matrix/animations/starlight_dual_sat_anim.h b/quantum/rgb_matrix/animations/starlight_dual_sat_anim.h
index 1994aba8a8..6def4eea09 100644
--- a/quantum/rgb_matrix/animations/starlight_dual_sat_anim.h
+++ b/quantum/rgb_matrix/animations/starlight_dual_sat_anim.h
@@ -4,10 +4,10 @@ RGB_MATRIX_EFFECT(STARLIGHT_DUAL_SAT)
void set_starlight_dual_sat_color(uint8_t i, effect_params_t* params) {
uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
- HSV hsv = rgb_matrix_config.hsv;
+ hsv_t hsv = rgb_matrix_config.hsv;
hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
hsv.s = hsv.s + random8_max((30 + 1 - -30) + -30);
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
diff --git a/quantum/rgb_matrix/animations/typing_heatmap_anim.h b/quantum/rgb_matrix/animations/typing_heatmap_anim.h
index d09bdc4631..0606738891 100644
--- a/quantum/rgb_matrix/animations/typing_heatmap_anim.h
+++ b/quantum/rgb_matrix/animations/typing_heatmap_anim.h
@@ -82,8 +82,8 @@ bool TYPING_HEATMAP(effect_params_t* params) {
uint8_t val = g_rgb_frame_buffer[row][col];
if (!HAS_ANY_FLAGS(g_led_config.flags[g_led_config.matrix_co[row][col]], params->flags)) continue;
- HSV hsv = {170 - qsub8(val, 85), rgb_matrix_config.hsv.s, scale8((qadd8(170, val) - 170) * 3, rgb_matrix_config.hsv.v)};
- RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
+ hsv_t hsv = {170 - qsub8(val, 85), rgb_matrix_config.hsv.s, scale8((qadd8(170, val) - 170) * 3, rgb_matrix_config.hsv.v)};
+ rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(g_led_config.matrix_co[row][col], rgb.r, rgb.g, rgb.b);
if (decrease_heatmap_values) {
diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c
index 70175f9d50..484d177546 100644
--- a/quantum/rgb_matrix/rgb_matrix.c
+++ b/quantum/rgb_matrix/rgb_matrix.c
@@ -35,7 +35,7 @@ const led_point_t k_rgb_matrix_center = {112, 32};
const led_point_t k_rgb_matrix_center = RGB_MATRIX_CENTER;
#endif
-__attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) {
+__attribute__((weak)) rgb_t rgb_matrix_hsv_to_rgb(hsv_t hsv) {
return hsv_to_rgb(hsv);
}
@@ -98,7 +98,7 @@ void eeconfig_update_rgb_matrix_default(void) {
dprintf("eeconfig_update_rgb_matrix_default\n");
rgb_matrix_config.enable = RGB_MATRIX_DEFAULT_ON;
rgb_matrix_config.mode = RGB_MATRIX_DEFAULT_MODE;
- rgb_matrix_config.hsv = (HSV){RGB_MATRIX_DEFAULT_HUE, RGB_MATRIX_DEFAULT_SAT, RGB_MATRIX_DEFAULT_VAL};
+ rgb_matrix_config.hsv = (hsv_t){RGB_MATRIX_DEFAULT_HUE, RGB_MATRIX_DEFAULT_SAT, RGB_MATRIX_DEFAULT_VAL};
rgb_matrix_config.speed = RGB_MATRIX_DEFAULT_SPD;
rgb_matrix_config.flags = RGB_MATRIX_DEFAULT_FLAGS;
eeconfig_flush_rgb_matrix(true);
@@ -143,8 +143,17 @@ void rgb_matrix_update_pwm_buffers(void) {
rgb_matrix_driver.flush();
}
+__attribute__((weak)) int rgb_matrix_led_index(int index) {
+#if defined(RGB_MATRIX_SPLIT)
+ if (!is_keyboard_left() && index >= k_rgb_matrix_split[0]) {
+ return index - k_rgb_matrix_split[0];
+ }
+#endif
+ return index;
+}
+
void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
- rgb_matrix_driver.set_color(index, red, green, blue);
+ rgb_matrix_driver.set_color(rgb_matrix_led_index(index), red, green, blue);
}
void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
@@ -404,7 +413,6 @@ struct rgb_matrix_limits_t rgb_matrix_get_limits(uint8_t iter) {
limits.led_min_index = RGB_MATRIX_LED_PROCESS_LIMIT * (iter);
limits.led_max_index = limits.led_min_index + RGB_MATRIX_LED_PROCESS_LIMIT;
if (limits.led_max_index > RGB_MATRIX_LED_COUNT) limits.led_max_index = RGB_MATRIX_LED_COUNT;
- uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;
if (is_keyboard_left() && (limits.led_max_index > k_rgb_matrix_split[0])) limits.led_max_index = k_rgb_matrix_split[0];
if (!(is_keyboard_left()) && (limits.led_min_index < k_rgb_matrix_split[0])) limits.led_min_index = k_rgb_matrix_split[0];
# else
@@ -414,9 +422,8 @@ struct rgb_matrix_limits_t rgb_matrix_get_limits(uint8_t iter) {
# endif
#else
# if defined(RGB_MATRIX_SPLIT)
- limits.led_min_index = 0;
- limits.led_max_index = RGB_MATRIX_LED_COUNT;
- const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;
+ limits.led_min_index = 0;
+ limits.led_max_index = RGB_MATRIX_LED_COUNT;
if (is_keyboard_left() && (limits.led_max_index > k_rgb_matrix_split[0])) limits.led_max_index = k_rgb_matrix_split[0];
if (!(is_keyboard_left()) && (limits.led_min_index < k_rgb_matrix_split[0])) limits.led_min_index = k_rgb_matrix_split[0];
# else
@@ -584,7 +591,7 @@ void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val) {
rgb_matrix_sethsv_eeprom_helper(hue, sat, val, true);
}
-HSV rgb_matrix_get_hsv(void) {
+hsv_t rgb_matrix_get_hsv(void) {
return rgb_matrix_config.hsv;
}
uint8_t rgb_matrix_get_hue(void) {
diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h
index ceb3185d1a..33f7e06a63 100644
--- a/quantum/rgb_matrix/rgb_matrix.h
+++ b/quantum/rgb_matrix/rgb_matrix.h
@@ -145,6 +145,8 @@ void eeconfig_update_rgb_matrix(void);
uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
+int rgb_matrix_led_index(int index);
+
void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
@@ -184,7 +186,7 @@ void rgb_matrix_step_reverse(void);
void rgb_matrix_step_reverse_noeeprom(void);
void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val);
void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
-HSV rgb_matrix_get_hsv(void);
+hsv_t rgb_matrix_get_hsv(void);
uint8_t rgb_matrix_get_hue(void);
uint8_t rgb_matrix_get_sat(void);
uint8_t rgb_matrix_get_val(void);
@@ -210,6 +212,7 @@ void rgb_matrix_decrease_speed_noeeprom(void);
led_flags_t rgb_matrix_get_flags(void);
void rgb_matrix_set_flags(led_flags_t flags);
void rgb_matrix_set_flags_noeeprom(led_flags_t flags);
+void rgb_matrix_update_pwm_buffers(void);
#ifndef RGBLIGHT_ENABLE
# define eeconfig_update_rgblight_current eeconfig_update_rgb_matrix
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c
index bf5209a9d3..3b45e82cb9 100644
--- a/quantum/rgb_matrix/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix/rgb_matrix_drivers.c
@@ -146,61 +146,11 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
# pragma message "You need to use a custom driver, or re-implement the WS2812 driver to use a different configuration."
# endif
-// LED color buffer
-rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_COUNT];
-bool ws2812_dirty = false;
-
-static void init(void) {
- ws2812_init();
- ws2812_dirty = false;
-}
-
-static void flush(void) {
- if (ws2812_dirty) {
- ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_COUNT);
- ws2812_dirty = false;
- }
-}
-
-// Set an led in the buffer to a color
-static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
-# if defined(RGB_MATRIX_SPLIT)
- const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;
- if (!is_keyboard_left()) {
- if (i >= k_rgb_matrix_split[0]) {
- i -= k_rgb_matrix_split[0];
- } else {
- return;
- }
- } else if (i >= k_rgb_matrix_split[0]) {
- return;
- }
-# endif
-
- if (rgb_matrix_ws2812_array[i].r == r && rgb_matrix_ws2812_array[i].g == g && rgb_matrix_ws2812_array[i].b == b) {
- return;
- }
-
- ws2812_dirty = true;
- rgb_matrix_ws2812_array[i].r = r;
- rgb_matrix_ws2812_array[i].g = g;
- rgb_matrix_ws2812_array[i].b = b;
-# ifdef WS2812_RGBW
- convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]);
-# endif
-}
-
-static void setled_all(uint8_t r, uint8_t g, uint8_t b) {
- for (int i = 0; i < ARRAY_SIZE(rgb_matrix_ws2812_array); i++) {
- setled(i, r, g, b);
- }
-}
-
const rgb_matrix_driver_t rgb_matrix_driver = {
- .init = init,
- .flush = flush,
- .set_color = setled,
- .set_color_all = setled_all,
+ .init = ws2812_init,
+ .flush = ws2812_flush,
+ .set_color = ws2812_set_color,
+ .set_color_all = ws2812_set_color_all,
};
#endif
diff --git a/quantum/rgb_matrix/rgb_matrix_types.h b/quantum/rgb_matrix/rgb_matrix_types.h
index 0a3fd7cc0d..0834a7067c 100644
--- a/quantum/rgb_matrix/rgb_matrix_types.h
+++ b/quantum/rgb_matrix/rgb_matrix_types.h
@@ -78,7 +78,7 @@ typedef union {
struct PACKED {
uint8_t enable : 2;
uint8_t mode : 6;
- HSV hsv;
+ hsv_t hsv;
uint8_t speed;
led_flags_t flags;
};
diff --git a/quantum/rgblight/rgblight.c b/quantum/rgblight/rgblight.c
index b0f2dfdc1d..ddccc9bae3 100644
--- a/quantum/rgblight/rgblight.c
+++ b/quantum/rgblight/rgblight.c
@@ -115,11 +115,6 @@ static bool pre_suspend_enabled;
animation_status_t animation_status = {};
#endif
-#ifndef LED_ARRAY
-rgb_led_t led[RGBLIGHT_LED_COUNT];
-# define LED_ARRAY led
-#endif
-
#ifdef RGBLIGHT_LAYERS
rgblight_segment_t const *const *rgblight_layers = NULL;
@@ -141,27 +136,30 @@ void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) {
rgblight_ranges.effect_num_leds = num_leds;
}
-__attribute__((weak)) RGB rgblight_hsv_to_rgb(HSV hsv) {
+__attribute__((weak)) rgb_t rgblight_hsv_to_rgb(hsv_t hsv) {
return hsv_to_rgb(hsv);
}
-void setrgb(uint8_t r, uint8_t g, uint8_t b, rgb_led_t *led1) {
- led1->r = r;
- led1->g = g;
- led1->b = b;
-#ifdef WS2812_RGBW
- led1->w = 0;
+uint8_t rgblight_led_index(uint8_t index) {
+#if defined(RGBLIGHT_LED_MAP)
+ return pgm_read_byte(&led_map[index]) - rgblight_ranges.clipping_start_pos;
+#else
+ return index - rgblight_ranges.clipping_start_pos;
#endif
}
-void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, rgb_led_t *led1) {
- HSV hsv = {hue, sat, val};
- RGB rgb = rgblight_hsv_to_rgb(hsv);
- setrgb(rgb.r, rgb.g, rgb.b, led1);
+void setrgb(uint8_t r, uint8_t g, uint8_t b, int index) {
+ rgblight_driver.set_color(rgblight_led_index(index), r, g, b);
}
-void sethsv(uint8_t hue, uint8_t sat, uint8_t val, rgb_led_t *led1) {
- sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, led1);
+void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, int index) {
+ hsv_t hsv = {hue, sat, val};
+ rgb_t rgb = rgblight_hsv_to_rgb(hsv);
+ setrgb(rgb.r, rgb.g, rgb.b, index);
+}
+
+void sethsv(uint8_t hue, uint8_t sat, uint8_t val, int index) {
+ sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, index);
}
void rgblight_check_config(void) {
@@ -515,9 +513,8 @@ void rgblight_decrease_speed_noeeprom(void) {
void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) {
if (rgblight_config.enable) {
- rgb_led_t tmp_led;
- sethsv(hue, sat, val, &tmp_led);
- rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
+ rgb_t rgb = hsv_to_rgb((hsv_t){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
+ rgblight_setrgb(rgb.r, rgb.g, rgb.b);
}
}
@@ -531,13 +528,12 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
rgblight_status.base_mode = mode_base_table[rgblight_config.mode];
if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
// same static color
- rgb_led_t tmp_led;
#ifdef RGBLIGHT_LAYERS_RETAIN_VAL
// needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
rgblight_config.val = val;
#endif
- sethsv(hue, sat, val, &tmp_led);
- rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
+ rgb_t rgb = hsv_to_rgb((hsv_t){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
+ rgblight_setrgb(rgb.r, rgb.g, rgb.b);
} else {
// all LEDs in same color
if (1 == 0) { // dummy
@@ -575,7 +571,7 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
_hue = hue - _hue;
}
dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
- sethsv(_hue, sat, val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]);
+ sethsv(_hue, sat, val, i + rgblight_ranges.effect_start_pos);
}
# ifdef RGBLIGHT_LAYERS_RETAIN_VAL
// needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
@@ -639,8 +635,8 @@ uint8_t rgblight_get_val(void) {
return rgblight_config.val;
}
-HSV rgblight_get_hsv(void) {
- return (HSV){rgblight_config.hue, rgblight_config.sat, rgblight_config.val};
+hsv_t rgblight_get_hsv(void) {
+ return (hsv_t){rgblight_config.hue, rgblight_config.sat, rgblight_config.val};
}
void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
@@ -649,12 +645,7 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
}
for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
- led[i].r = r;
- led[i].g = g;
- led[i].b = b;
-#ifdef WS2812_RGBW
- led[i].w = 0;
-#endif
+ rgblight_driver.set_color(rgblight_led_index(i), r, g, b);
}
rgblight_set();
}
@@ -664,12 +655,7 @@ void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) {
return;
}
- led[index].r = r;
- led[index].g = g;
- led[index].b = b;
-#ifdef WS2812_RGBW
- led[index].w = 0;
-#endif
+ rgblight_driver.set_color(rgblight_led_index(index), r, g, b);
rgblight_set();
}
@@ -678,9 +664,8 @@ void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) {
return;
}
- rgb_led_t tmp_led;
- sethsv(hue, sat, val, &tmp_led);
- rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
+ rgb_t rgb = hsv_to_rgb((hsv_t){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
+ rgblight_setrgb_at(rgb.r, rgb.g, rgb.b, index);
}
#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE)
@@ -701,12 +686,7 @@ void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8
}
for (uint8_t i = start; i < end; i++) {
- led[i].r = r;
- led[i].g = g;
- led[i].b = b;
-#ifdef WS2812_RGBW
- led[i].w = 0;
-#endif
+ rgblight_driver.set_color(rgblight_led_index(i), r, g, b);
}
rgblight_set();
}
@@ -716,9 +696,8 @@ void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start,
return;
}
- rgb_led_t tmp_led;
- sethsv(hue, sat, val, &tmp_led);
- rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
+ rgb_t rgb = hsv_to_rgb((hsv_t){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
+ rgblight_setrgb_range(rgb.r, rgb.g, rgb.b, start, end);
}
#ifndef RGBLIGHT_SPLIT
@@ -785,12 +764,12 @@ static void rgblight_layers_write(void) {
break; // No more segments
}
// Write segment.count LEDs
- rgb_led_t *const limit = &led[MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT)];
- for (rgb_led_t *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) {
+ int limit = MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT);
+ for (int i = segment.index; i < limit; i++) {
# ifdef RGBLIGHT_LAYERS_RETAIN_VAL
- sethsv(segment.hue, segment.sat, current_val, led_ptr);
+ sethsv(segment.hue, segment.sat, current_val, i);
# else
- sethsv(segment.hue, segment.sat, segment.val, led_ptr);
+ sethsv(segment.hue, segment.sat, segment.val, i);
# endif
}
segment_ptr++;
@@ -897,17 +876,9 @@ void rgblight_wakeup(void) {
#endif
void rgblight_set(void) {
- rgb_led_t *start_led;
- uint8_t num_leds = rgblight_ranges.clipping_num_leds;
-
if (!rgblight_config.enable) {
for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
- led[i].r = 0;
- led[i].g = 0;
- led[i].b = 0;
-#ifdef WS2812_RGBW
- led[i].w = 0;
-#endif
+ rgblight_driver.set_color(rgblight_led_index(i), 0, 0, 0);
}
}
@@ -923,22 +894,7 @@ void rgblight_set(void) {
}
#endif
-#ifdef RGBLIGHT_LED_MAP
- rgb_led_t led0[RGBLIGHT_LED_COUNT];
- for (uint8_t i = 0; i < RGBLIGHT_LED_COUNT; i++) {
- led0[i] = led[pgm_read_byte(&led_map[i])];
- }
- start_led = led0 + rgblight_ranges.clipping_start_pos;
-#else
- start_led = led + rgblight_ranges.clipping_start_pos;
-#endif
-
-#ifdef WS2812_RGBW
- for (uint8_t i = 0; i < num_leds; i++) {
- convert_rgb_to_rgbw(&start_led[i]);
- }
-#endif
- rgblight_driver.setleds(start_led, num_leds);
+ rgblight_driver.flush();
}
#ifdef RGBLIGHT_SPLIT
@@ -1222,7 +1178,7 @@ void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue);
- sethsv(hue, rgblight_config.sat, rgblight_config.val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]);
+ sethsv(hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
}
rgblight_set();
@@ -1259,13 +1215,8 @@ void rgblight_effect_snake(animation_status_t *anim) {
# endif
for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
- rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos;
- ledp->r = 0;
- ledp->g = 0;
- ledp->b = 0;
-# ifdef WS2812_RGBW
- ledp->w = 0;
-# endif
+ rgblight_driver.set_color(rgblight_led_index(i + rgblight_ranges.effect_start_pos), 0, 0, 0);
+
for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
k = pos + j * increment;
if (k > RGBLIGHT_LED_COUNT) {
@@ -1275,7 +1226,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
k = k + rgblight_ranges.effect_num_leds;
}
if (i == k) {
- sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp);
+ sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), i + rgblight_ranges.effect_start_pos);
}
}
}
@@ -1320,26 +1271,16 @@ void rgblight_effect_knight(animation_status_t *anim) {
# endif
// Set all the LEDs to 0
for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
- led[i].r = 0;
- led[i].g = 0;
- led[i].b = 0;
-# ifdef WS2812_RGBW
- led[i].w = 0;
-# endif
+ rgblight_driver.set_color(rgblight_led_index(i), 0, 0, 0);
}
// Determine which LEDs should be lit up
for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos;
if (i >= low_bound && i <= high_bound) {
- sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (rgb_led_t *)&led[cur]);
+ sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, cur);
} else {
- led[cur].r = 0;
- led[cur].g = 0;
- led[cur].b = 0;
-# ifdef WS2812_RGBW
- led[cur].w = 0;
-# endif
+ rgblight_driver.set_color(rgblight_led_index(cur), 0, 0, 0);
}
}
rgblight_set();
@@ -1384,7 +1325,7 @@ void rgblight_effect_christmas(animation_status_t *anim) {
for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue;
- sethsv(local_hue, rgblight_config.sat, val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]);
+ sethsv(local_hue, rgblight_config.sat, val, i + rgblight_ranges.effect_start_pos);
}
rgblight_set();
@@ -1401,43 +1342,25 @@ void rgblight_effect_christmas(animation_status_t *anim) {
__attribute__((weak)) const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};
void rgblight_effect_rgbtest(animation_status_t *anim) {
- static uint8_t maxval = 0;
- uint8_t g;
- uint8_t r;
- uint8_t b;
-
- if (maxval == 0) {
- rgb_led_t tmp_led;
- sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led);
- maxval = tmp_led.r;
- }
- g = r = b = 0;
- switch (anim->pos) {
- case 0:
- r = maxval;
- break;
- case 1:
- g = maxval;
- break;
- case 2:
- b = maxval;
- break;
- }
+ uint8_t val = rgblight_get_val();
+
+ uint8_t r = anim->pos & 1 ? val : 0;
+ uint8_t g = anim->pos & 2 ? val : 0;
+ uint8_t b = anim->pos & 4 ? val : 0;
rgblight_setrgb(r, g, b);
- anim->pos = (anim->pos + 1) % 3;
+ anim->pos = (anim->pos + 1) % 8;
}
#endif
#ifdef RGBLIGHT_EFFECT_ALTERNATING
void rgblight_effect_alternating(animation_status_t *anim) {
for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) {
- rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos;
if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) {
- sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
+ sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
} else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) {
- sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
+ sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
} else {
- sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp);
+ sethsv(rgblight_config.hue, rgblight_config.sat, 0, i + rgblight_ranges.effect_start_pos);
}
}
rgblight_set();
@@ -1449,7 +1372,7 @@ void rgblight_effect_alternating(animation_status_t *anim) {
__attribute__((weak)) const uint8_t RGBLED_TWINKLE_INTERVALS[] PROGMEM = {30, 15, 5};
typedef struct PACKED {
- HSV hsv;
+ hsv_t hsv;
uint8_t life;
uint8_t max_life;
} TwinkleState;
@@ -1475,7 +1398,7 @@ void rgblight_effect_twinkle(animation_status_t *anim) {
for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) {
TwinkleState *t = &(led_twinkle_state[i]);
- HSV * c = &(t->hsv);
+ hsv_t * c = &(t->hsv);
if (!random_color) {
c->h = rgblight_config.hue;
@@ -1504,8 +1427,7 @@ void rgblight_effect_twinkle(animation_status_t *anim) {
// This LED is off, and was NOT selected to start brightening
}
- rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos;
- sethsv(c->h, c->s, c->v, ledp);
+ sethsv(c->h, c->s, c->v, i + rgblight_ranges.effect_start_pos);
}
rgblight_set();
diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h
index 0ed67ff6e3..f4b6e621e4 100644
--- a/quantum/rgblight/rgblight.h
+++ b/quantum/rgblight/rgblight.h
@@ -169,7 +169,6 @@ enum RGBLIGHT_EFFECT_MODE {
#include "rgblight_drivers.h"
#include "progmem.h"
#include "eeconfig.h"
-#include "ws2812.h"
#include "color.h"
#ifdef RGBLIGHT_LAYERS
@@ -363,7 +362,7 @@ uint8_t rgblight_get_hue(void);
uint8_t rgblight_get_sat(void);
uint8_t rgblight_get_val(void);
bool rgblight_is_enabled(void);
-HSV rgblight_get_hsv(void);
+hsv_t rgblight_get_hsv(void);
/* === qmk_firmware (core)internal Functions === */
void rgblight_init(void);
diff --git a/quantum/rgblight/rgblight_drivers.c b/quantum/rgblight/rgblight_drivers.c
index 76e9031aec..ef986ee13c 100644
--- a/quantum/rgblight/rgblight_drivers.c
+++ b/quantum/rgblight/rgblight_drivers.c
@@ -7,24 +7,20 @@
# include "ws2812.h"
const rgblight_driver_t rgblight_driver = {
- .init = ws2812_init,
- .setleds = ws2812_setleds,
+ .init = ws2812_init,
+ .set_color = ws2812_set_color,
+ .set_color_all = ws2812_set_color_all,
+ .flush = ws2812_flush,
};
#elif defined(RGBLIGHT_APA102)
# include "apa102.h"
-// Temporary shim
-static void apa102_setleds(rgb_led_t *ledarray, uint16_t number_of_leds) {
- for (uint16_t i = 0; i < number_of_leds; i++) {
- apa102_set_color(i, ledarray[i].r, ledarray[i].g, ledarray[i].b);
- }
- apa102_flush();
-}
-
const rgblight_driver_t rgblight_driver = {
- .init = apa102_init,
- .setleds = apa102_setleds,
+ .init = apa102_init,
+ .set_color = apa102_set_color,
+ .set_color_all = apa102_set_color_all,
+ .flush = apa102_flush,
};
#endif
diff --git a/quantum/rgblight/rgblight_drivers.h b/quantum/rgblight/rgblight_drivers.h
index af28b918e1..16fb4cebd6 100644
--- a/quantum/rgblight/rgblight_drivers.h
+++ b/quantum/rgblight/rgblight_drivers.h
@@ -4,11 +4,12 @@
#pragma once
#include <stdint.h>
-#include "color.h"
typedef struct {
void (*init)(void);
- void (*setleds)(rgb_led_t *ledarray, uint16_t number_of_leds);
+ void (*set_color)(int index, uint8_t red, uint8_t green, uint8_t blue);
+ void (*set_color_all)(uint8_t red, uint8_t green, uint8_t blue);
+ void (*flush)(void);
} rgblight_driver_t;
extern const rgblight_driver_t rgblight_driver;
diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c
index 6c1aeb284d..f66b2ad89f 100644
--- a/quantum/split_common/transactions.c
+++ b/quantum/split_common/transactions.c
@@ -733,7 +733,7 @@ static bool pointing_handlers_master(matrix_row_t master_matrix[], matrix_row_t
return okay;
}
-extern const pointing_device_driver_t pointing_device_driver;
+extern const pointing_device_driver_t *pointing_device_driver;
static void pointing_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
# if defined(POINTING_DEVICE_LEFT)
@@ -753,18 +753,18 @@ static void pointing_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
last_exec = timer_read32();
# endif
- uint16_t temp_cpi = !pointing_device_driver.get_cpi ? 0 : pointing_device_driver.get_cpi(); // check for NULL
+ uint16_t temp_cpi = !pointing_device_driver->get_cpi ? 0 : pointing_device_driver->get_cpi(); // check for NULL
split_shared_memory_lock();
split_slave_pointing_sync_t pointing;
memcpy(&pointing, &split_shmem->pointing, sizeof(split_slave_pointing_sync_t));
split_shared_memory_unlock();
- if (pointing.cpi && pointing.cpi != temp_cpi && pointing_device_driver.set_cpi) {
- pointing_device_driver.set_cpi(pointing.cpi);
+ if (pointing.cpi && pointing.cpi != temp_cpi && pointing_device_driver->set_cpi) {
+ pointing_device_driver->set_cpi(pointing.cpi);
}
- pointing.report = pointing_device_driver.get_report((report_mouse_t){0});
+ pointing.report = pointing_device_driver->get_report((report_mouse_t){0});
// Now update the checksum given that the pointing has been written to
pointing.checksum = crc8(&pointing.report, sizeof(report_mouse_t));
diff --git a/quantum/util.h b/quantum/util.h
index 94d9f22317..61ec7ac153 100644
--- a/quantum/util.h
+++ b/quantum/util.h
@@ -4,6 +4,7 @@
#pragma once
+#include "bits.h"
#include "bitwise.h"
// convert to string