forked from mirrors/qmk_userspace
		
	Allow overriding of all functions in wonderland.c (#7198)
* f * Allow overriding of all functions in wonderland.c - needed for custom LED functions in keymap.c * Example of layer indication via LEDs optimize * Use newer led_update_kb and led_update_user hooks - these allow overriding without use of __attribute((weak))__ * Update led documentation a bit - clarify some of the wording around how to use led_update_user * Update led_update_user example * Update audio example to be complete * trailing spaces smh * spaces * spaces * smh * Less code is good * Update docs/custom_quantum_functions.md Co-Authored-By: fauxpark <fauxpark@gmail.com> * Update docs/custom_quantum_functions.md Co-Authored-By: fauxpark <fauxpark@gmail.com> * Update docs/custom_quantum_functions.md Co-Authored-By: fauxpark <fauxpark@gmail.com> * Update docs/custom_quantum_functions.md Co-Authored-By: fauxpark <fauxpark@gmail.com> * Update docs/custom_quantum_functions.md Co-Authored-By: fauxpark <fauxpark@gmail.com> * Update docs/custom_quantum_functions.md Co-Authored-By: fauxpark <fauxpark@gmail.com>
This commit is contained in:
		
					parent
					
						
							
								0270d4d5a1
							
						
					
				
			
			
				commit
				
					
						e62ab7e259
					
				
			
		
					 3 changed files with 72 additions and 52 deletions
				
			
		| 
						 | 
					@ -114,7 +114,15 @@ Two more deprecated functions exist that provide the LED state as a `uint8_t`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter.
 | 
					This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You must return either `true` or `false` from this function, depending on whether you want to override the keyboard-level implementation.
 | 
					By convention, return `true` from `led_update_user()` to get the `led_update_kb()` hook to run its code, and
 | 
				
			||||||
 | 
					return `false` when you would prefer not to run the code in `led_update_kb()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Some examples include:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - overriding the LEDs to use them for something else like layer indication
 | 
				
			||||||
 | 
					    - return `false` because you do not want the `_kb()` function to run, as it would override your layer behavior.
 | 
				
			||||||
 | 
					  - play a sound when an LED turns on or off.
 | 
				
			||||||
 | 
					    - return `true` because you want the `_kb` function to run, and this is in addition to the default LED behavior.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead.
 | 
					?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,7 +130,8 @@ You must return either `true` or `false` from this function, depending on whethe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```c
 | 
					```c
 | 
				
			||||||
bool led_update_kb(led_t led_state) {
 | 
					bool led_update_kb(led_t led_state) {
 | 
				
			||||||
    if(led_update_user(led_state)) {
 | 
					    bool res = led_update_user(led_state);
 | 
				
			||||||
 | 
					    if(res) {
 | 
				
			||||||
        if (led_state.num_lock) {
 | 
					        if (led_state.num_lock) {
 | 
				
			||||||
            writePinLow(B0);
 | 
					            writePinLow(B0);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
| 
						 | 
					@ -148,40 +157,29 @@ bool led_update_kb(led_t led_state) {
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            writePinHigh(B4);
 | 
					            writePinHigh(B4);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Example `led_update_user()` Implementation
 | 
					### Example `led_update_user()` Implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This incomplete example would play a sound if Caps Lock is turned on or off. It returns `true`, because you also want the LEDs to maintain their state.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```c
 | 
					```c
 | 
				
			||||||
 | 
					#ifdef AUDIO_ENABLE
 | 
				
			||||||
 | 
					  float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND);
 | 
				
			||||||
 | 
					  float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool led_update_user(led_t led_state) {
 | 
					bool led_update_user(led_t led_state) {
 | 
				
			||||||
    if (led_state.num_lock) {
 | 
					    #ifdef AUDIO_ENABLE
 | 
				
			||||||
        writePinLow(B0);
 | 
					    static uint8_t caps_state = 0;
 | 
				
			||||||
    } else {
 | 
					    if (caps_state != led_state.caps_lock) {
 | 
				
			||||||
        writePinHigh(B0);
 | 
					        led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off);
 | 
				
			||||||
    }
 | 
					        caps_state = led_state.caps_lock;
 | 
				
			||||||
    if (led_state.caps_lock) {
 | 
					 | 
				
			||||||
        writePinLow(B1);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        writePinHigh(B1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (led_state.scroll_lock) {
 | 
					 | 
				
			||||||
        writePinLow(B2);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        writePinHigh(B2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (led_state.compose) {
 | 
					 | 
				
			||||||
        writePinLow(B3);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        writePinHigh(B3);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (led_state.kana) {
 | 
					 | 
				
			||||||
        writePinLow(B4);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        writePinHigh(B4);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,3 +22,33 @@ RGB_RMOD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
 | 
				
			||||||
          _______,          KC_LALT, _______, _______,          _______,                   KC_RALT,                            _______ \
 | 
					          _______,          KC_LALT, _______, _______,          _______,                   KC_RALT,                            _______ \
 | 
				
			||||||
   )
 | 
					   )
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef USE_LEDS_FOR_LAYERS
 | 
				
			||||||
 | 
					// example of how to use LEDs as layer indicators
 | 
				
			||||||
 | 
					static uint8_t top = 1;
 | 
				
			||||||
 | 
					static uint8_t middle = 0;
 | 
				
			||||||
 | 
					static uint8_t bottom = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					layer_state_t layer_state_set_user(layer_state_t state) {
 | 
				
			||||||
 | 
					    top = middle = bottom = 0;
 | 
				
			||||||
 | 
					    switch (get_highest_layer(state)) {
 | 
				
			||||||
 | 
					    case _BASE:
 | 
				
			||||||
 | 
					        top = 1;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case _FUNC:
 | 
				
			||||||
 | 
					        middle = 1;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default: //  for any other layers, or the default layer
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  return state;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// override kb level function
 | 
				
			||||||
 | 
					bool led_update_user(led_t usb_led) {
 | 
				
			||||||
 | 
					    writePin(B1, !top);
 | 
				
			||||||
 | 
					    writePin(B2, !middle);
 | 
				
			||||||
 | 
					    writePin(B3, !bottom);
 | 
				
			||||||
 | 
					    return false; // we are using LEDs for something else override kb
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
#include "wonderland.h"
 | 
					#include "wonderland.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute__ ((weak))
 | 
				
			||||||
void matrix_init_kb(void) {
 | 
					void matrix_init_kb(void) {
 | 
				
			||||||
	// put your keyboard start-up code here
 | 
						// put your keyboard start-up code here
 | 
				
			||||||
	// runs once when the firmware starts up
 | 
						// runs once when the firmware starts up
 | 
				
			||||||
| 
						 | 
					@ -7,12 +8,14 @@ void matrix_init_kb(void) {
 | 
				
			||||||
	led_init_ports();
 | 
						led_init_ports();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute__ ((weak))
 | 
				
			||||||
void matrix_scan_kb(void) {
 | 
					void matrix_scan_kb(void) {
 | 
				
			||||||
	// put your looping keyboard code here
 | 
						// put your looping keyboard code here
 | 
				
			||||||
	// runs every cycle (a lot)
 | 
						// runs every cycle (a lot)
 | 
				
			||||||
	matrix_scan_user();
 | 
						matrix_scan_user();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute__ ((weak))
 | 
				
			||||||
void led_init_ports(void) {
 | 
					void led_init_ports(void) {
 | 
				
			||||||
    // * Set our LED pins as output
 | 
					    // * Set our LED pins as output
 | 
				
			||||||
    setPinOutput(B1);
 | 
					    setPinOutput(B1);
 | 
				
			||||||
| 
						 | 
					@ -20,23 +23,12 @@ void led_init_ports(void) {
 | 
				
			||||||
    setPinOutput(B3);
 | 
					    setPinOutput(B3);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void led_set_kb(uint8_t usb_led) {
 | 
					bool led_update_kb(led_t led_state) {
 | 
				
			||||||
	if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
 | 
					    bool runDefault = led_update_user(led_state);
 | 
				
			||||||
        writePinLow(B1);
 | 
					    if (runDefault) {
 | 
				
			||||||
    } else {
 | 
					      writePin(B1, !led_state.num_lock);
 | 
				
			||||||
        writePinHigh(B1);
 | 
					      writePin(B2, !led_state.caps_lock);
 | 
				
			||||||
 | 
					      writePin(B3, !led_state.scroll_lock);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return runDefault;
 | 
				
			||||||
    if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
 | 
					 | 
				
			||||||
        writePinLow(B2);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        writePinHigh(B2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
 | 
					 | 
				
			||||||
        writePinLow(B3);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        writePinHigh(B3);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
	led_set_user(usb_led);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue