diff options
| author | Ryan <fauxpark@gmail.com> | 2022-10-15 14:33:24 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-15 14:33:24 +1100 |
| commit | f0b2bfd5ca5b416a9c7c9bef8c2850f1084bd106 (patch) | |
| tree | 2e3cc54b3fb899f05f15bf8008bcbb4816b5ffb5 | |
| parent | 19aed5e999ef177a2ff0b2b705443bde9c70588c (diff) | |
Programmable Button API refactor and improve docs (#18641)
| -rw-r--r-- | docs/feature_programmable_button.md | 200 | ||||
| -rw-r--r-- | quantum/action.c | 1 | ||||
| -rw-r--r-- | quantum/keyboard.c | 7 | ||||
| -rw-r--r-- | quantum/process_keycode/process_programmable_button.c | 4 | ||||
| -rw-r--r-- | quantum/programmable_button.c | 27 | ||||
| -rw-r--r-- | quantum/programmable_button.h | 75 |
6 files changed, 224 insertions, 90 deletions
diff --git a/docs/feature_programmable_button.md b/docs/feature_programmable_button.md index b1ef555d16..1982b8295e 100644 --- a/docs/feature_programmable_button.md +++ b/docs/feature_programmable_button.md | |||
| @@ -1,74 +1,144 @@ | |||
| 1 | ## Programmable Button | 1 | # Programmable Button :id=programmable-button |
| 2 | 2 | ||
| 3 | Programmable button is a feature that can be used to send keys that have no | 3 | 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. |
| 4 | predefined meaning. | ||
| 5 | This means they can be processed on the host side by custom software without | ||
| 6 | colliding without the operating system trying to interpret these keys. | ||
| 7 | 4 | ||
| 8 | The keycodes are emitted according to the HID usage | 5 | 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`). |
| 9 | "Telephony Device Page" (0x0B), "Programmable button usage" (0x07). | ||
| 10 | On Linux (> 5.14) they are handled automatically and translated to `KEY_MACRO#` | ||
| 11 | keycodes. | ||
| 12 | (Up to `KEY_MACRO30`) | ||
| 13 | 6 | ||
| 14 | ### Enabling Programmable Button support | 7 | ?> 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. |
| 15 | 8 | ||
| 16 | To enable Programmable Button, add the following line to your keymap’s `rules.mk`: | 9 | ## Usage :id=usage |
| 17 | 10 | ||
| 18 | ```c | 11 | Add the following to your `rules.mk`: |
| 12 | |||
| 13 | ```make | ||
| 19 | PROGRAMMABLE_BUTTON_ENABLE = yes | 14 | PROGRAMMABLE_BUTTON_ENABLE = yes |
| 20 | ``` | 15 | ``` |
| 21 | 16 | ||
| 22 | ### Mapping | 17 | ## Keycodes :id=keycodes |
| 23 | |||
| 24 | In your keymap you can use the following keycodes to map key presses to Programmable Buttons: | ||
| 25 | |||
| 26 | |Key |Description | | ||
| 27 | |------------------------|----------------------| | ||
| 28 | |`PROGRAMMABLE_BUTTON_1` |Programmable button 1 | | ||
| 29 | |`PROGRAMMABLE_BUTTON_2` |Programmable button 2 | | ||
| 30 | |`PROGRAMMABLE_BUTTON_3` |Programmable button 3 | | ||
| 31 | |`PROGRAMMABLE_BUTTON_4` |Programmable button 4 | | ||
| 32 | |`PROGRAMMABLE_BUTTON_5` |Programmable button 5 | | ||
| 33 | |`PROGRAMMABLE_BUTTON_6` |Programmable button 6 | | ||
| 34 | |`PROGRAMMABLE_BUTTON_7` |Programmable button 7 | | ||
| 35 | |`PROGRAMMABLE_BUTTON_8` |Programmable button 8 | | ||
| 36 | |`PROGRAMMABLE_BUTTON_9` |Programmable button 9 | | ||
| 37 | |`PROGRAMMABLE_BUTTON_10`|Programmable button 10| | ||
| 38 | |`PROGRAMMABLE_BUTTON_11`|Programmable button 11| | ||
| 39 | |`PROGRAMMABLE_BUTTON_12`|Programmable button 12| | ||
| 40 | |`PROGRAMMABLE_BUTTON_13`|Programmable button 13| | ||
| 41 | |`PROGRAMMABLE_BUTTON_14`|Programmable button 14| | ||
| 42 | |`PROGRAMMABLE_BUTTON_15`|Programmable button 15| | ||
| 43 | |`PROGRAMMABLE_BUTTON_16`|Programmable button 16| | ||
| 44 | |`PROGRAMMABLE_BUTTON_17`|Programmable button 17| | ||
| 45 | |`PROGRAMMABLE_BUTTON_18`|Programmable button 18| | ||
| 46 | |`PROGRAMMABLE_BUTTON_19`|Programmable button 19| | ||
| 47 | |`PROGRAMMABLE_BUTTON_20`|Programmable button 20| | ||
| 48 | |`PROGRAMMABLE_BUTTON_21`|Programmable button 21| | ||
| 49 | |`PROGRAMMABLE_BUTTON_22`|Programmable button 22| | ||
| 50 | |`PROGRAMMABLE_BUTTON_23`|Programmable button 23| | ||
| 51 | |`PROGRAMMABLE_BUTTON_24`|Programmable button 24| | ||
| 52 | |`PROGRAMMABLE_BUTTON_25`|Programmable button 25| | ||
| 53 | |`PROGRAMMABLE_BUTTON_26`|Programmable button 26| | ||
| 54 | |`PROGRAMMABLE_BUTTON_27`|Programmable button 27| | ||
| 55 | |`PROGRAMMABLE_BUTTON_28`|Programmable button 28| | ||
| 56 | |`PROGRAMMABLE_BUTTON_29`|Programmable button 29| | ||
| 57 | |`PROGRAMMABLE_BUTTON_30`|Programmable button 30| | ||
| 58 | |`PROGRAMMABLE_BUTTON_31`|Programmable button 31| | ||
| 59 | |`PROGRAMMABLE_BUTTON_32`|Programmable button 32| | ||
| 60 | |`PB_1` to `PB_32` |Aliases for keymaps | | ||
| 61 | |||
| 62 | ### API | ||
| 63 | |||
| 64 | You can also use a dedicated API defined in `programmable_button.h` to interact with this feature: | ||
| 65 | 18 | ||
| 66 | ``` | 19 | |Key |Aliases|Description | |
| 67 | void programmable_button_clear(void); | 20 | |------------------------|-------|----------------------| |
| 68 | void programmable_button_send(void); | 21 | |`PROGRAMMABLE_BUTTON_1` |`PB_1` |Programmable button 1 | |
| 69 | void programmable_button_on(uint8_t code); | 22 | |`PROGRAMMABLE_BUTTON_2` |`PB_2` |Programmable button 2 | |
| 70 | void programmable_button_off(uint8_t code); | 23 | |`PROGRAMMABLE_BUTTON_3` |`PB_3` |Programmable button 3 | |
| 71 | bool programmable_button_is_on(uint8_t code); | 24 | |`PROGRAMMABLE_BUTTON_4` |`PB_4` |Programmable button 4 | |
| 72 | uint32_t programmable_button_get_report(void); | 25 | |`PROGRAMMABLE_BUTTON_5` |`PB_5` |Programmable button 5 | |
| 73 | void programmable_button_set_report(uint32_t report); | 26 | |`PROGRAMMABLE_BUTTON_6` |`PB_6` |Programmable button 6 | |
| 74 | ``` | 27 | |`PROGRAMMABLE_BUTTON_7` |`PB_7` |Programmable button 7 | |
| 28 | |`PROGRAMMABLE_BUTTON_8` |`PB_8` |Programmable button 8 | | ||
| 29 | |`PROGRAMMABLE_BUTTON_9` |`PB_9` |Programmable button 9 | | ||
| 30 | |`PROGRAMMABLE_BUTTON_10`|`PB_10`|Programmable button 10| | ||
| 31 | |`PROGRAMMABLE_BUTTON_11`|`PB_11`|Programmable button 11| | ||
| 32 | |`PROGRAMMABLE_BUTTON_12`|`PB_12`|Programmable button 12| | ||
| 33 | |`PROGRAMMABLE_BUTTON_13`|`PB_13`|Programmable button 13| | ||
| 34 | |`PROGRAMMABLE_BUTTON_14`|`PB_14`|Programmable button 14| | ||
| 35 | |`PROGRAMMABLE_BUTTON_15`|`PB_15`|Programmable button 15| | ||
| 36 | |`PROGRAMMABLE_BUTTON_16`|`PB_16`|Programmable button 16| | ||
| 37 | |`PROGRAMMABLE_BUTTON_17`|`PB_17`|Programmable button 17| | ||
| 38 | |`PROGRAMMABLE_BUTTON_18`|`PB_18`|Programmable button 18| | ||
| 39 | |`PROGRAMMABLE_BUTTON_19`|`PB_19`|Programmable button 19| | ||
| 40 | |`PROGRAMMABLE_BUTTON_20`|`PB_20`|Programmable button 20| | ||
| 41 | |`PROGRAMMABLE_BUTTON_21`|`PB_21`|Programmable button 21| | ||
| 42 | |`PROGRAMMABLE_BUTTON_22`|`PB_22`|Programmable button 22| | ||
| 43 | |`PROGRAMMABLE_BUTTON_23`|`PB_23`|Programmable button 23| | ||
| 44 | |`PROGRAMMABLE_BUTTON_24`|`PB_24`|Programmable button 24| | ||
| 45 | |`PROGRAMMABLE_BUTTON_25`|`PB_25`|Programmable button 25| | ||
| 46 | |`PROGRAMMABLE_BUTTON_26`|`PB_26`|Programmable button 26| | ||
| 47 | |`PROGRAMMABLE_BUTTON_27`|`PB_27`|Programmable button 27| | ||
| 48 | |`PROGRAMMABLE_BUTTON_28`|`PB_28`|Programmable button 28| | ||
| 49 | |`PROGRAMMABLE_BUTTON_29`|`PB_29`|Programmable button 29| | ||
| 50 | |`PROGRAMMABLE_BUTTON_30`|`PB_30`|Programmable button 30| | ||
| 51 | |`PROGRAMMABLE_BUTTON_31`|`PB_31`|Programmable button 31| | ||
| 52 | |`PROGRAMMABLE_BUTTON_32`|`PB_32`|Programmable button 32| | ||
| 53 | |||
| 54 | ## API :id=api | ||
| 55 | |||
| 56 | ### `void programmable_button_clear(void)` :id=api-programmable-button-clear | ||
| 57 | |||
| 58 | Clear the programmable button report. | ||
| 59 | |||
| 60 | --- | ||
| 61 | |||
| 62 | ### `void programmable_button_add(uint8_t index)` :id=api-programmable-button-add | ||
| 63 | |||
| 64 | Set the state of a button. | ||
| 65 | |||
| 66 | #### Arguments :id=api-programmable-button-add-arguments | ||
| 67 | |||
| 68 | - `uint8_t index` | ||
| 69 | The index of the button to press, from 0 to 31. | ||
| 70 | |||
| 71 | --- | ||
| 72 | |||
| 73 | ### `void programmable_button_remove(uint8_t index)` :id=api-programmable-button-remove | ||
| 74 | |||
| 75 | Reset the state of a button. | ||
| 76 | |||
| 77 | #### Arguments :id=api-programmable-button-remove-arguments | ||
| 78 | |||
| 79 | - `uint8_t index` | ||
| 80 | The index of the button to release, from 0 to 31. | ||
| 81 | |||
| 82 | --- | ||
| 83 | |||
| 84 | ### `void programmable_button_register(uint8_t index)` :id=api-programmable-button-register | ||
| 85 | |||
| 86 | Set the state of a button, and flush the report. | ||
| 87 | |||
| 88 | #### Arguments :id=api-programmable-button-register-arguments | ||
| 89 | |||
| 90 | - `uint8_t index` | ||
| 91 | The index of the button to press, from 0 to 31. | ||
| 92 | |||
| 93 | --- | ||
| 94 | |||
| 95 | ### `void programmable_button_unregister(uint8_t index)` :id=api-programmable-button-unregister | ||
| 96 | |||
| 97 | Reset the state of a button, and flush the report. | ||
| 98 | |||
| 99 | #### Arguments :id=api-programmable-button-unregister-arguments | ||
| 100 | |||
| 101 | - `uint8_t index` | ||
| 102 | The index of the button to release, from 0 to 31. | ||
| 103 | |||
| 104 | --- | ||
| 105 | |||
| 106 | ### `bool programmable_button_is_on(uint8_t index)` :id=api-programmable-button-is-on | ||
| 107 | |||
| 108 | Get the state of a button. | ||
| 109 | |||
| 110 | #### Arguments :id=api-programmable-button-is-on-arguments | ||
| 111 | |||
| 112 | - `uint8_t index` | ||
| 113 | The index of the button to check, from 0 to 31. | ||
| 114 | |||
| 115 | #### Return Value :id=api-programmable-button-is-on-return | ||
| 116 | |||
| 117 | `true` if the button is pressed. | ||
| 118 | |||
| 119 | --- | ||
| 120 | |||
| 121 | ### `void programmable_button_flush(void)` :id=api-programmable-button-flush | ||
| 122 | |||
| 123 | Send the programmable button report to the host. | ||
| 124 | |||
| 125 | --- | ||
| 126 | |||
| 127 | ### `uint32_t programmable_button_get_report(void)` :id=api-programmable-button-get-report | ||
| 128 | |||
| 129 | Get the programmable button report. | ||
| 130 | |||
| 131 | #### Return Value :id=api-programmable-button-get-report-return | ||
| 132 | |||
| 133 | The bitmask of programmable button states. | ||
| 134 | |||
| 135 | --- | ||
| 136 | |||
| 137 | ### `void programmable_button_set_report(uint32_t report)` :id=api-programmable-button-set-report | ||
| 138 | |||
| 139 | Set the programmable button report. | ||
| 140 | |||
| 141 | #### Arguments :id=api-programmable-button-set-report-arguments | ||
| 142 | |||
| 143 | - `uint32_t report` | ||
| 144 | A bitmask of programmable button states. | ||
diff --git a/quantum/action.c b/quantum/action.c index 78322e4a83..abf9834d2f 100644 --- a/quantum/action.c +++ b/quantum/action.c | |||
| @@ -1081,7 +1081,6 @@ void clear_keyboard_but_mods_and_keys() { | |||
| 1081 | #endif | 1081 | #endif |
| 1082 | #ifdef PROGRAMMABLE_BUTTON_ENABLE | 1082 | #ifdef PROGRAMMABLE_BUTTON_ENABLE |
| 1083 | programmable_button_clear(); | 1083 | programmable_button_clear(); |
| 1084 | programmable_button_send(); | ||
| 1085 | #endif | 1084 | #endif |
| 1086 | } | 1085 | } |
| 1087 | 1086 | ||
diff --git a/quantum/keyboard.c b/quantum/keyboard.c index 280532a5fd..eb5e4b583a 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c | |||
| @@ -66,9 +66,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 66 | #ifdef JOYSTICK_ENABLE | 66 | #ifdef JOYSTICK_ENABLE |
| 67 | # include "process_joystick.h" | 67 | # include "process_joystick.h" |
| 68 | #endif | 68 | #endif |
| 69 | #ifdef PROGRAMMABLE_BUTTON_ENABLE | ||
| 70 | # include "programmable_button.h" | ||
| 71 | #endif | ||
| 72 | #ifdef HD44780_ENABLE | 69 | #ifdef HD44780_ENABLE |
| 73 | # include "hd44780.h" | 70 | # include "hd44780.h" |
| 74 | #endif | 71 | #endif |
| @@ -669,10 +666,6 @@ void keyboard_task(void) { | |||
| 669 | digitizer_task(); | 666 | digitizer_task(); |
| 670 | #endif | 667 | #endif |
| 671 | 668 | ||
| 672 | #ifdef PROGRAMMABLE_BUTTON_ENABLE | ||
| 673 | programmable_button_send(); | ||
| 674 | #endif | ||
| 675 | |||
| 676 | #ifdef BLUETOOTH_ENABLE | 669 | #ifdef BLUETOOTH_ENABLE |
| 677 | bluetooth_task(); | 670 | bluetooth_task(); |
| 678 | #endif | 671 | #endif |
diff --git a/quantum/process_keycode/process_programmable_button.c b/quantum/process_keycode/process_programmable_button.c index c6e77faacc..6379698848 100644 --- a/quantum/process_keycode/process_programmable_button.c +++ b/quantum/process_keycode/process_programmable_button.c | |||
| @@ -22,9 +22,9 @@ bool process_programmable_button(uint16_t keycode, keyrecord_t *record) { | |||
| 22 | if (keycode >= PROGRAMMABLE_BUTTON_MIN && keycode <= PROGRAMMABLE_BUTTON_MAX) { | 22 | if (keycode >= PROGRAMMABLE_BUTTON_MIN && keycode <= PROGRAMMABLE_BUTTON_MAX) { |
| 23 | uint8_t button = keycode - PROGRAMMABLE_BUTTON_MIN + 1; | 23 | uint8_t button = keycode - PROGRAMMABLE_BUTTON_MIN + 1; |
| 24 | if (record->event.pressed) { | 24 | if (record->event.pressed) { |
| 25 | programmable_button_on(button); | 25 | programmable_button_register(button); |
| 26 | } else { | 26 | } else { |
| 27 | programmable_button_off(button); | 27 | programmable_button_unregister(button); |
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | return true; | 30 | return true; |
diff --git a/quantum/programmable_button.c b/quantum/programmable_button.c index a3ef42d82b..b6c9ad3189 100644 --- a/quantum/programmable_button.c +++ b/quantum/programmable_button.c | |||
| @@ -24,27 +24,38 @@ static uint32_t programmable_button_report = 0; | |||
| 24 | 24 | ||
| 25 | void programmable_button_clear(void) { | 25 | void programmable_button_clear(void) { |
| 26 | programmable_button_report = 0; | 26 | programmable_button_report = 0; |
| 27 | programmable_button_flush(); | ||
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | void programmable_button_send(void) { | 30 | void programmable_button_add(uint8_t index) { |
| 30 | host_programmable_button_send(programmable_button_report); | ||
| 31 | } | ||
| 32 | |||
| 33 | void programmable_button_on(uint8_t index) { | ||
| 34 | programmable_button_report |= REPORT_BIT(index); | 31 | programmable_button_report |= REPORT_BIT(index); |
| 35 | } | 32 | } |
| 36 | 33 | ||
| 37 | void programmable_button_off(uint8_t index) { | 34 | void programmable_button_remove(uint8_t index) { |
| 38 | programmable_button_report &= ~REPORT_BIT(index); | 35 | programmable_button_report &= ~REPORT_BIT(index); |
| 39 | } | 36 | } |
| 40 | 37 | ||
| 38 | void programmable_button_register(uint8_t index) { | ||
| 39 | programmable_button_add(index); | ||
| 40 | programmable_button_flush(); | ||
| 41 | } | ||
| 42 | |||
| 43 | void programmable_button_unregister(uint8_t index) { | ||
| 44 | programmable_button_remove(index); | ||
| 45 | programmable_button_flush(); | ||
| 46 | } | ||
| 47 | |||
| 41 | bool programmable_button_is_on(uint8_t index) { | 48 | bool programmable_button_is_on(uint8_t index) { |
| 42 | return !!(programmable_button_report & REPORT_BIT(index)); | 49 | return !!(programmable_button_report & REPORT_BIT(index)); |
| 43 | }; | 50 | } |
| 51 | |||
| 52 | void programmable_button_flush(void) { | ||
| 53 | host_programmable_button_send(programmable_button_report); | ||
| 54 | } | ||
| 44 | 55 | ||
| 45 | uint32_t programmable_button_get_report(void) { | 56 | uint32_t programmable_button_get_report(void) { |
| 46 | return programmable_button_report; | 57 | return programmable_button_report; |
| 47 | }; | 58 | } |
| 48 | 59 | ||
| 49 | void programmable_button_set_report(uint32_t report) { | 60 | void programmable_button_set_report(uint32_t report) { |
| 50 | programmable_button_report = report; | 61 | programmable_button_report = report; |
diff --git a/quantum/programmable_button.h b/quantum/programmable_button.h index e89b8b9fd6..e8c916d75c 100644 --- a/quantum/programmable_button.h +++ b/quantum/programmable_button.h | |||
| @@ -19,12 +19,73 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 19 | 19 | ||
| 20 | #include <stdint.h> | 20 | #include <stdint.h> |
| 21 | #include <stdbool.h> | 21 | #include <stdbool.h> |
| 22 | #include "report.h" | ||
| 23 | 22 | ||
| 24 | void programmable_button_clear(void); | 23 | /** |
| 25 | void programmable_button_send(void); | 24 | * \defgroup programmable_button |
| 26 | void programmable_button_on(uint8_t index); | 25 | * |
| 27 | void programmable_button_off(uint8_t index); | 26 | * HID Programmable Buttons |
| 28 | bool programmable_button_is_on(uint8_t index); | 27 | * \{ |
| 28 | */ | ||
| 29 | |||
| 30 | /** | ||
| 31 | * \brief Clear the programmable button report. | ||
| 32 | */ | ||
| 33 | void programmable_button_clear(void); | ||
| 34 | |||
| 35 | /** | ||
| 36 | * \brief Set the state of a button. | ||
| 37 | * | ||
| 38 | * \param index The index of the button to press, from 0 to 31. | ||
| 39 | */ | ||
| 40 | void programmable_button_add(uint8_t index); | ||
| 41 | |||
| 42 | /** | ||
| 43 | * \brief Reset the state of a button. | ||
| 44 | * | ||
| 45 | * \param index The index of the button to release, from 0 to 31. | ||
| 46 | */ | ||
| 47 | void programmable_button_remove(uint8_t index); | ||
| 48 | |||
| 49 | /** | ||
| 50 | * \brief Set the state of a button, and flush the report. | ||
| 51 | * | ||
| 52 | * \param index The index of the button to press, from 0 to 31. | ||
| 53 | */ | ||
| 54 | void programmable_button_register(uint8_t index); | ||
| 55 | |||
| 56 | /** | ||
| 57 | * \brief Reset the state of a button, and flush the report. | ||
| 58 | * | ||
| 59 | * \param index The index of the button to release, from 0 to 31. | ||
| 60 | */ | ||
| 61 | void programmable_button_unregister(uint8_t index); | ||
| 62 | |||
| 63 | /** | ||
| 64 | * \brief Get the state of a button. | ||
| 65 | * | ||
| 66 | * \param index The index of the button to check, from 0 to 31. | ||
| 67 | * | ||
| 68 | * \return `true` if the button is pressed. | ||
| 69 | */ | ||
| 70 | bool programmable_button_is_on(uint8_t index); | ||
| 71 | |||
| 72 | /** | ||
| 73 | * \brief Send the programmable button report to the host. | ||
| 74 | */ | ||
| 75 | void programmable_button_flush(void); | ||
| 76 | |||
| 77 | /** | ||
| 78 | * \brief Get the programmable button report. | ||
| 79 | * | ||
| 80 | * \return The bitmask of programmable button states. | ||
| 81 | */ | ||
| 29 | uint32_t programmable_button_get_report(void); | 82 | uint32_t programmable_button_get_report(void); |
| 30 | void programmable_button_set_report(uint32_t report); | 83 | |
| 84 | /** | ||
| 85 | * \brief Set the programmable button report. | ||
| 86 | * | ||
| 87 | * \param report A bitmask of programmable button states. | ||
| 88 | */ | ||
| 89 | void programmable_button_set_report(uint32_t report); | ||
| 90 | |||
| 91 | /** \} */ | ||
