1
0
Fork 0
forked from forks/qmk_firmware

Programmable Button API refactor and improve docs (#18641)

This commit is contained in:
Ryan 2022-10-15 14:33:24 +11:00 committed by GitHub
parent 19aed5e999
commit f0b2bfd5ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 220 additions and 86 deletions

View file

@ -1,74 +1,144 @@
## Programmable Button
# Programmable Button :id=programmable-button
Programmable button is a feature that can be used to send keys that have no
predefined meaning.
This means they can be processed on the host side by custom software without
colliding without the operating system trying to interpret these keys.
Programmable Buttons are keys that have no predefined meaning. This means they can be processed on the host side by custom software without the operating system trying to interpret them.
The keycodes are emitted according to the HID usage
"Telephony Device Page" (0x0B), "Programmable button usage" (0x07).
On Linux (> 5.14) they are handled automatically and translated to `KEY_MACRO#`
keycodes.
(Up to `KEY_MACRO30`)
The keycodes are emitted according to the HID Telephony Device page (`0x0B`), Programmable Button usage (`0x07`). On Linux (> 5.14) they are handled automatically and translated to `KEY_MACRO#` keycodes (up to `KEY_MACRO30`).
### Enabling Programmable Button support
?> Currently there is no known support in Windows or macOS. It may be possible to write a custom HID driver to receive these usages, but this is out of the scope of the QMK documentation.
To enable Programmable Button, add the following line to your keymaps `rules.mk`:
## Usage :id=usage
```c
Add the following to your `rules.mk`:
```make
PROGRAMMABLE_BUTTON_ENABLE = yes
```
### Mapping
## Keycodes :id=keycodes
In your keymap you can use the following keycodes to map key presses to Programmable Buttons:
|Key |Aliases|Description |
|------------------------|-------|----------------------|
|`PROGRAMMABLE_BUTTON_1` |`PB_1` |Programmable button 1 |
|`PROGRAMMABLE_BUTTON_2` |`PB_2` |Programmable button 2 |
|`PROGRAMMABLE_BUTTON_3` |`PB_3` |Programmable button 3 |
|`PROGRAMMABLE_BUTTON_4` |`PB_4` |Programmable button 4 |
|`PROGRAMMABLE_BUTTON_5` |`PB_5` |Programmable button 5 |
|`PROGRAMMABLE_BUTTON_6` |`PB_6` |Programmable button 6 |
|`PROGRAMMABLE_BUTTON_7` |`PB_7` |Programmable button 7 |
|`PROGRAMMABLE_BUTTON_8` |`PB_8` |Programmable button 8 |
|`PROGRAMMABLE_BUTTON_9` |`PB_9` |Programmable button 9 |
|`PROGRAMMABLE_BUTTON_10`|`PB_10`|Programmable button 10|
|`PROGRAMMABLE_BUTTON_11`|`PB_11`|Programmable button 11|
|`PROGRAMMABLE_BUTTON_12`|`PB_12`|Programmable button 12|
|`PROGRAMMABLE_BUTTON_13`|`PB_13`|Programmable button 13|
|`PROGRAMMABLE_BUTTON_14`|`PB_14`|Programmable button 14|
|`PROGRAMMABLE_BUTTON_15`|`PB_15`|Programmable button 15|
|`PROGRAMMABLE_BUTTON_16`|`PB_16`|Programmable button 16|
|`PROGRAMMABLE_BUTTON_17`|`PB_17`|Programmable button 17|
|`PROGRAMMABLE_BUTTON_18`|`PB_18`|Programmable button 18|
|`PROGRAMMABLE_BUTTON_19`|`PB_19`|Programmable button 19|
|`PROGRAMMABLE_BUTTON_20`|`PB_20`|Programmable button 20|
|`PROGRAMMABLE_BUTTON_21`|`PB_21`|Programmable button 21|
|`PROGRAMMABLE_BUTTON_22`|`PB_22`|Programmable button 22|
|`PROGRAMMABLE_BUTTON_23`|`PB_23`|Programmable button 23|
|`PROGRAMMABLE_BUTTON_24`|`PB_24`|Programmable button 24|
|`PROGRAMMABLE_BUTTON_25`|`PB_25`|Programmable button 25|
|`PROGRAMMABLE_BUTTON_26`|`PB_26`|Programmable button 26|
|`PROGRAMMABLE_BUTTON_27`|`PB_27`|Programmable button 27|
|`PROGRAMMABLE_BUTTON_28`|`PB_28`|Programmable button 28|
|`PROGRAMMABLE_BUTTON_29`|`PB_29`|Programmable button 29|
|`PROGRAMMABLE_BUTTON_30`|`PB_30`|Programmable button 30|
|`PROGRAMMABLE_BUTTON_31`|`PB_31`|Programmable button 31|
|`PROGRAMMABLE_BUTTON_32`|`PB_32`|Programmable button 32|
|Key |Description |
|------------------------|----------------------|
|`PROGRAMMABLE_BUTTON_1` |Programmable button 1 |
|`PROGRAMMABLE_BUTTON_2` |Programmable button 2 |
|`PROGRAMMABLE_BUTTON_3` |Programmable button 3 |
|`PROGRAMMABLE_BUTTON_4` |Programmable button 4 |
|`PROGRAMMABLE_BUTTON_5` |Programmable button 5 |
|`PROGRAMMABLE_BUTTON_6` |Programmable button 6 |
|`PROGRAMMABLE_BUTTON_7` |Programmable button 7 |
|`PROGRAMMABLE_BUTTON_8` |Programmable button 8 |
|`PROGRAMMABLE_BUTTON_9` |Programmable button 9 |
|`PROGRAMMABLE_BUTTON_10`|Programmable button 10|
|`PROGRAMMABLE_BUTTON_11`|Programmable button 11|
|`PROGRAMMABLE_BUTTON_12`|Programmable button 12|
|`PROGRAMMABLE_BUTTON_13`|Programmable button 13|
|`PROGRAMMABLE_BUTTON_14`|Programmable button 14|
|`PROGRAMMABLE_BUTTON_15`|Programmable button 15|
|`PROGRAMMABLE_BUTTON_16`|Programmable button 16|
|`PROGRAMMABLE_BUTTON_17`|Programmable button 17|
|`PROGRAMMABLE_BUTTON_18`|Programmable button 18|
|`PROGRAMMABLE_BUTTON_19`|Programmable button 19|
|`PROGRAMMABLE_BUTTON_20`|Programmable button 20|
|`PROGRAMMABLE_BUTTON_21`|Programmable button 21|
|`PROGRAMMABLE_BUTTON_22`|Programmable button 22|
|`PROGRAMMABLE_BUTTON_23`|Programmable button 23|
|`PROGRAMMABLE_BUTTON_24`|Programmable button 24|
|`PROGRAMMABLE_BUTTON_25`|Programmable button 25|
|`PROGRAMMABLE_BUTTON_26`|Programmable button 26|
|`PROGRAMMABLE_BUTTON_27`|Programmable button 27|
|`PROGRAMMABLE_BUTTON_28`|Programmable button 28|
|`PROGRAMMABLE_BUTTON_29`|Programmable button 29|
|`PROGRAMMABLE_BUTTON_30`|Programmable button 30|
|`PROGRAMMABLE_BUTTON_31`|Programmable button 31|
|`PROGRAMMABLE_BUTTON_32`|Programmable button 32|
|`PB_1` to `PB_32` |Aliases for keymaps |
## API :id=api
### API
### `void programmable_button_clear(void)` :id=api-programmable-button-clear
You can also use a dedicated API defined in `programmable_button.h` to interact with this feature:
Clear the programmable button report.
```
void programmable_button_clear(void);
void programmable_button_send(void);
void programmable_button_on(uint8_t code);
void programmable_button_off(uint8_t code);
bool programmable_button_is_on(uint8_t code);
uint32_t programmable_button_get_report(void);
void programmable_button_set_report(uint32_t report);
```
---
### `void programmable_button_add(uint8_t index)` :id=api-programmable-button-add
Set the state of a button.
#### Arguments :id=api-programmable-button-add-arguments
- `uint8_t index`
The index of the button to press, from 0 to 31.
---
### `void programmable_button_remove(uint8_t index)` :id=api-programmable-button-remove
Reset the state of a button.
#### Arguments :id=api-programmable-button-remove-arguments
- `uint8_t index`
The index of the button to release, from 0 to 31.
---
### `void programmable_button_register(uint8_t index)` :id=api-programmable-button-register
Set the state of a button, and flush the report.
#### Arguments :id=api-programmable-button-register-arguments
- `uint8_t index`
The index of the button to press, from 0 to 31.
---
### `void programmable_button_unregister(uint8_t index)` :id=api-programmable-button-unregister
Reset the state of a button, and flush the report.
#### Arguments :id=api-programmable-button-unregister-arguments
- `uint8_t index`
The index of the button to release, from 0 to 31.
---
### `bool programmable_button_is_on(uint8_t index)` :id=api-programmable-button-is-on
Get the state of a button.
#### Arguments :id=api-programmable-button-is-on-arguments
- `uint8_t index`
The index of the button to check, from 0 to 31.
#### Return Value :id=api-programmable-button-is-on-return
`true` if the button is pressed.
---
### `void programmable_button_flush(void)` :id=api-programmable-button-flush
Send the programmable button report to the host.
---
### `uint32_t programmable_button_get_report(void)` :id=api-programmable-button-get-report
Get the programmable button report.
#### Return Value :id=api-programmable-button-get-report-return
The bitmask of programmable button states.
---
### `void programmable_button_set_report(uint32_t report)` :id=api-programmable-button-set-report
Set the programmable button report.
#### Arguments :id=api-programmable-button-set-report-arguments
- `uint32_t report`
A bitmask of programmable button states.

View file

@ -1081,7 +1081,6 @@ void clear_keyboard_but_mods_and_keys() {
#endif
#ifdef PROGRAMMABLE_BUTTON_ENABLE
programmable_button_clear();
programmable_button_send();
#endif
}

View file

@ -66,9 +66,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef JOYSTICK_ENABLE
# include "process_joystick.h"
#endif
#ifdef PROGRAMMABLE_BUTTON_ENABLE
# include "programmable_button.h"
#endif
#ifdef HD44780_ENABLE
# include "hd44780.h"
#endif
@ -669,10 +666,6 @@ void keyboard_task(void) {
digitizer_task();
#endif
#ifdef PROGRAMMABLE_BUTTON_ENABLE
programmable_button_send();
#endif
#ifdef BLUETOOTH_ENABLE
bluetooth_task();
#endif

View file

@ -22,9 +22,9 @@ bool process_programmable_button(uint16_t keycode, keyrecord_t *record) {
if (keycode >= PROGRAMMABLE_BUTTON_MIN && keycode <= PROGRAMMABLE_BUTTON_MAX) {
uint8_t button = keycode - PROGRAMMABLE_BUTTON_MIN + 1;
if (record->event.pressed) {
programmable_button_on(button);
programmable_button_register(button);
} else {
programmable_button_off(button);
programmable_button_unregister(button);
}
}
return true;

View file

@ -24,27 +24,38 @@ static uint32_t programmable_button_report = 0;
void programmable_button_clear(void) {
programmable_button_report = 0;
programmable_button_flush();
}
void programmable_button_send(void) {
host_programmable_button_send(programmable_button_report);
}
void programmable_button_on(uint8_t index) {
void programmable_button_add(uint8_t index) {
programmable_button_report |= REPORT_BIT(index);
}
void programmable_button_off(uint8_t index) {
void programmable_button_remove(uint8_t index) {
programmable_button_report &= ~REPORT_BIT(index);
}
void programmable_button_register(uint8_t index) {
programmable_button_add(index);
programmable_button_flush();
}
void programmable_button_unregister(uint8_t index) {
programmable_button_remove(index);
programmable_button_flush();
}
bool programmable_button_is_on(uint8_t index) {
return !!(programmable_button_report & REPORT_BIT(index));
};
}
void programmable_button_flush(void) {
host_programmable_button_send(programmable_button_report);
}
uint32_t programmable_button_get_report(void) {
return programmable_button_report;
};
}
void programmable_button_set_report(uint32_t report) {
programmable_button_report = report;

View file

@ -19,12 +19,73 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include <stdbool.h>
#include "report.h"
void programmable_button_clear(void);
void programmable_button_send(void);
void programmable_button_on(uint8_t index);
void programmable_button_off(uint8_t index);
bool programmable_button_is_on(uint8_t index);
/**
* \defgroup programmable_button
*
* HID Programmable Buttons
* \{
*/
/**
* \brief Clear the programmable button report.
*/
void programmable_button_clear(void);
/**
* \brief Set the state of a button.
*
* \param index The index of the button to press, from 0 to 31.
*/
void programmable_button_add(uint8_t index);
/**
* \brief Reset the state of a button.
*
* \param index The index of the button to release, from 0 to 31.
*/
void programmable_button_remove(uint8_t index);
/**
* \brief Set the state of a button, and flush the report.
*
* \param index The index of the button to press, from 0 to 31.
*/
void programmable_button_register(uint8_t index);
/**
* \brief Reset the state of a button, and flush the report.
*
* \param index The index of the button to release, from 0 to 31.
*/
void programmable_button_unregister(uint8_t index);
/**
* \brief Get the state of a button.
*
* \param index The index of the button to check, from 0 to 31.
*
* \return `true` if the button is pressed.
*/
bool programmable_button_is_on(uint8_t index);
/**
* \brief Send the programmable button report to the host.
*/
void programmable_button_flush(void);
/**
* \brief Get the programmable button report.
*
* \return The bitmask of programmable button states.
*/
uint32_t programmable_button_get_report(void);
void programmable_button_set_report(uint32_t report);
/**
* \brief Set the programmable button report.
*
* \param report A bitmask of programmable button states.
*/
void programmable_button_set_report(uint32_t report);
/** \} */