aboutsummaryrefslogtreecommitdiffstats
path: root/quantum/process_keycode/process_rgb.c
blob: c76166342f19202469b5af2bb727735cd1f9bf9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* 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 "rgb.h"

typedef void (*rgb_func_pointer)(void);

/**
 * Wrapper for inc/dec rgb keycode
 * 
 * noinline to optimise for firmware size not speed (not in hot path) 
 */
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();
    }
}

/**
 * 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) {
#ifndef SPLIT_KEYBOARD
    if (record->event.pressed) {
#else
    // Split keyboards need to trigger on key-up for edge-case issue
    if (!record->event.pressed) {
#endif
        uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
        switch (keycode) {
            case RGB_TOG:
                rgblight_toggle();
                return false;
            case RGB_MODE_FORWARD:
                handleKeycodeRGB(shifted, rgblight_step, rgblight_step_reverse);
                return false;
            case RGB_MODE_REVERSE:
                handleKeycodeRGB(shifted, rgblight_step_reverse, rgblight_step);
                return false;
            case RGB_HUI:
                handleKeycodeRGB(shifted, rgblight_increase_hue, rgblight_decrease_hue);
                return false;
            case RGB_HUD:
                handleKeycodeRGB(shifted, rgblight_decrease_hue, rgblight_increase_hue);
                return false;
            case RGB_SAI:
                handleKeycodeRGB(shifted, rgblight_increase_sat, rgblight_decrease_sat);
                return false;
            case RGB_SAD:
                handleKeycodeRGB(shifted, rgblight_decrease_sat, rgblight_increase_sat);
                return false;
            case RGB_VAI:
                handleKeycodeRGB(shifted, rgblight_increase_val, rgblight_decrease_val);
                return false;
            case RGB_VAD:
                handleKeycodeRGB(shifted, rgblight_decrease_val, rgblight_increase_val);
                return false;
            case RGB_SPI:
                handleKeycodeRGB(shifted, rgblight_increase_speed, rgblight_decrease_speed);
                return false;
            case RGB_SPD:
                handleKeycodeRGB(shifted, rgblight_decrease_speed, rgblight_increase_speed);
                return false;
            case RGB_MODE_PLAIN:
                rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
                return false;
            case RGB_MODE_BREATHE:
#ifdef RGBLIGHT_EFFECT_BREATHING
                handleKeycodeRGBMode(RGBLIGHT_MODE_BREATHING, RGBLIGHT_MODE_BREATHING_end);
#endif
                return false;
            case RGB_MODE_RAINBOW:
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
                handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_MOOD, RGBLIGHT_MODE_RAINBOW_MOOD_end);
#endif
                return false;
            case RGB_MODE_SWIRL:
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
                handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_SWIRL, RGBLIGHT_MODE_RAINBOW_SWIRL_end);
#endif
                return false;
            case RGB_MODE_SNAKE:
#ifdef RGBLIGHT_EFFECT_SNAKE
                handleKeycodeRGBMode(RGBLIGHT_MODE_SNAKE, RGBLIGHT_MODE_SNAKE_end);
#endif
                return false;
            case RGB_MODE_KNIGHT:
#ifdef RGBLIGHT_EFFECT_KNIGHT
                handleKeycodeRGBMode(RGBLIGHT_MODE_KNIGHT, RGBLIGHT_MODE_KNIGHT_end);
#endif
                return false;
            case RGB_MODE_XMAS:
#ifdef RGBLIGHT_EFFECT_CHRISTMAS
                rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
#endif
                return false;
            case RGB_MODE_GRADIENT:
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
                handleKeycodeRGBMode(RGBLIGHT_MODE_STATIC_GRADIENT, RGBLIGHT_MODE_STATIC_GRADIENT_end);
#endif
                return false;
            case RGB_MODE_RGBTEST:
#ifdef RGBLIGHT_EFFECT_RGB_TEST
                rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
#endif
                return false;
        }
    }

    return true;
}