From 6124d254f94ab6c115172311e0878a159b8ddcaa Mon Sep 17 00:00:00 2001 From: John Drogo Date: Sun, 11 Sep 2022 00:05:15 -0700 Subject: [PATCH 1/8] fix(usb): add USB_DC_RESUME to supported states All credit for this one goes to @xudongzheng (thanks for helping debug this!). Should fix the issue where keyboards go unresponsive after their host machine wakes from sleep due to the USB driver entering an error state. I was able to both reliably reproduce the issue before the patch goes in and confirmed it no longer occurs post patch. The `USB_DC_RESUME` state indicates the host event has resumed the connection. Adding it to the list of valid connection states to prevent the error when waking from sleep. Zephyr API Link: https://docs.zephyrproject.org/apidoc/latest/group____usb__device__controller__api.html#gac09e3e0af1a2b41a5bfbad91f900baf7 fixes #1372 --- app/src/usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/usb.c b/app/src/usb.c index 5f170ee665a6..aa2d3e754dcd 100644 --- a/app/src/usb.c +++ b/app/src/usb.c @@ -33,6 +33,7 @@ enum zmk_usb_conn_state zmk_usb_get_conn_state() { switch (usb_status) { case USB_DC_SUSPEND: case USB_DC_CONFIGURED: + case USB_DC_RESUME: return ZMK_USB_CONN_HID; case USB_DC_DISCONNECTED: From 3f28a55452eb34d02876e0c98bdc4be9e00936c3 Mon Sep 17 00:00:00 2001 From: Robert U <978080+urob@users.noreply.github.com> Date: Sun, 11 Sep 2022 21:06:04 -0400 Subject: [PATCH 2/8] fix(docs): Fix ambiguous tap-preferred desc. --- docs/docs/behaviors/hold-tap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 528b9aec7424..667e5df88f73 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -28,7 +28,7 @@ We call this the 'hold-preferred' flavor of hold-taps. While this flavor may wor - The 'hold-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired or another key is pressed. - The 'balanced' flavor will trigger the hold behavior when the `tapping-term-ms` has expired or another key is pressed and released. -- The 'tap-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired. It triggers the tap behavior when another key is pressed. +- The 'tap-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired. Pressing another key within `tapping-term-ms` does not affect the decision. - The 'tap-unless-interrupted' flavor triggers a hold behavior only when another key is pressed before `tapping-term-ms` has expired. It triggers the tap behavior in all other situations. When the hold-tap key is released and the hold behavior has not been triggered, the tap behavior will trigger. From 5513f16d7102d41d5708fabca2f6ce404fb3286c Mon Sep 17 00:00:00 2001 From: down Date: Sat, 28 May 2022 17:58:59 +0700 Subject: [PATCH 3/8] feat(widget): add bongo cat --- app/include/zmk/display/widgets/bongo_cat.h | 21 ++ app/src/display/status_screen.c | 9 + app/src/display/widgets/CMakeLists.txt | 2 + app/src/display/widgets/Kconfig | 23 +++ app/src/display/widgets/bongo_cat.c | 106 ++++++++++ app/src/display/widgets/bongo_img.c | 211 ++++++++++++++++++++ 6 files changed, 372 insertions(+) create mode 100644 app/include/zmk/display/widgets/bongo_cat.h create mode 100644 app/src/display/widgets/bongo_cat.c create mode 100644 app/src/display/widgets/bongo_img.c diff --git a/app/include/zmk/display/widgets/bongo_cat.h b/app/include/zmk/display/widgets/bongo_cat.h new file mode 100644 index 000000000000..4465639d3f02 --- /dev/null +++ b/app/include/zmk/display/widgets/bongo_cat.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include + +struct zmk_widget_bongo_cat { + sys_snode_t node; + lv_obj_t *obj; +#if !IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) + lv_anim_t anim; +#endif +}; + +int zmk_widget_bongo_cat_init(struct zmk_widget_bongo_cat *widget, lv_obj_t *parent); +lv_obj_t *zmk_widget_bongo_cat_obj(struct zmk_widget_bongo_cat *widget); diff --git a/app/src/display/status_screen.c b/app/src/display/status_screen.c index 6ace1925af8b..50428f955d78 100644 --- a/app/src/display/status_screen.c +++ b/app/src/display/status_screen.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,10 @@ static struct zmk_widget_layer_status layer_status_widget; static struct zmk_widget_wpm_status wpm_status_widget; #endif +#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT) +static struct zmk_widget_bongo_cat bongo_cat_widget; +#endif + lv_obj_t *zmk_display_status_screen() { lv_obj_t *screen; @@ -70,6 +75,10 @@ lv_obj_t *zmk_display_status_screen() { zmk_widget_wpm_status_init(&wpm_status_widget, screen); lv_obj_align(zmk_widget_wpm_status_obj(&wpm_status_widget), NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -12, 0); +#endif +#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT) + zmk_widget_bongo_cat_init(&bongo_cat_widget, screen); + lv_obj_align(zmk_widget_bongo_cat_obj(&bongo_cat_widget), NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); #endif return screen; } diff --git a/app/src/display/widgets/CMakeLists.txt b/app/src/display/widgets/CMakeLists.txt index fbf07072768d..c7684896c46f 100644 --- a/app/src/display/widgets/CMakeLists.txt +++ b/app/src/display/widgets/CMakeLists.txt @@ -6,3 +6,5 @@ target_sources_ifdef(CONFIG_ZMK_WIDGET_OUTPUT_STATUS app PRIVATE output_status.c target_sources_ifdef(CONFIG_ZMK_WIDGET_PERIPHERAL_STATUS app PRIVATE peripheral_status.c) target_sources_ifdef(CONFIG_ZMK_WIDGET_LAYER_STATUS app PRIVATE layer_status.c) target_sources_ifdef(CONFIG_ZMK_WIDGET_WPM_STATUS app PRIVATE wpm_status.c) +target_sources_ifdef(CONFIG_ZMK_WIDGET_BONGO_CAT app PRIVATE bongo_cat.c) +target_sources_ifdef(CONFIG_ZMK_WIDGET_BONGO_CAT app PRIVATE bongo_img.c) diff --git a/app/src/display/widgets/Kconfig b/app/src/display/widgets/Kconfig index 96e7e16d3099..49bc46b36178 100644 --- a/app/src/display/widgets/Kconfig +++ b/app/src/display/widgets/Kconfig @@ -33,4 +33,27 @@ config ZMK_WIDGET_WPM_STATUS select LVGL_USE_LABEL select ZMK_WPM +config ZMK_WIDGET_BONGO_CAT + bool "Widget for displaying bongo cat" + depends on !ZMK_SPLIT || ZMK_SPLIT_BLE_ROLE_CENTRAL + select LVGL_USE_LABEL + select LVGL_USE_IMG + select LVGL_USE_ANIMATION if !ZMK_WIDGET_BONGO_CAT_INTERACTIVE + +if ZMK_WIDGET_BONGO_CAT + +config ZMK_WIDGET_BONGO_CAT_INTERACTIVE + bool "Bongo cat responds to key press" + default y + +if !ZMK_WIDGET_BONGO_CAT_INTERACTIVE + +config ZMK_WIDGET_BONGO_CAT_ANIMATION_INTERVAL + int "Time delay in ms for bongo cat animation" + default 531 + +endif + +endif # ZMK_WIDGET_BONGO_CAT + endmenu diff --git a/app/src/display/widgets/bongo_cat.c b/app/src/display/widgets/bongo_cat.c new file mode 100644 index 000000000000..5d2ef14cc7b9 --- /dev/null +++ b/app/src/display/widgets/bongo_cat.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#include +#include +#include + +#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) +#include +#endif + +static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); + +LV_IMG_DECLARE(left); +LV_IMG_DECLARE(right); + +#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) +LV_IMG_DECLARE(none); +LV_IMG_DECLARE(both); + +enum bongo_state { + bongo_state_none, + bongo_state_left, + bongo_state_right, +} current_bongo_state; + +const void *images[] = { + &none, + &left, + &right, + &both +}; +#else +const void *images[] = { + &left, + &right +}; + +void set_bongo_state(void *var, lv_anim_value_t val) { + lv_img_set_src( (lv_obj_t *)var, images[val]); +} +#endif /* IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) */ + +int zmk_widget_bongo_cat_init(struct zmk_widget_bongo_cat *widget, lv_obj_t *parent) { + widget->obj = lv_img_create(parent, NULL); + +#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) + lv_img_set_src(widget->obj, &none); + current_bongo_state = bongo_state_none; +#else + lv_anim_init(&widget->anim); + lv_anim_set_exec_cb(&widget->anim, (lv_anim_exec_xcb_t) set_bongo_state); + lv_anim_set_var(&widget->anim, widget->obj); + lv_anim_set_time(&widget->anim, CONFIG_ZMK_WIDGET_BONGO_CAT_ANIMATION_INTERVAL); + lv_anim_set_values(&widget->anim, 0, 1); + lv_anim_set_repeat_count(&widget->anim, LV_ANIM_REPEAT_INFINITE); + lv_anim_set_repeat_delay(&widget->anim, CONFIG_ZMK_WIDGET_BONGO_CAT_ANIMATION_INTERVAL); + lv_anim_start(&widget->anim); +#endif /* IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) */ + + sys_slist_append(&widgets, &widget->node); + + return 0; +} + +lv_obj_t *zmk_widget_bongo_cat_obj(struct zmk_widget_bongo_cat *widget) { + return widget->obj; +} + +#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) +void set_bongo_state(lv_obj_t *img, struct zmk_position_state_changed *ev) { + if (ev == NULL) { + return; + } + + uint8_t tmp = bongo_state_left; + if (ev->state) { + if (current_bongo_state & (bongo_state_left | bongo_state_right)) { + tmp = bongo_state_left | bongo_state_right; + } + } else { + if (current_bongo_state ^ (bongo_state_left | bongo_state_right)) { + tmp = bongo_state_none; + } + } + + current_bongo_state = tmp; + lv_img_set_src(img, images[current_bongo_state]); +} + +int bongo_cat_listener(const zmk_event_t *eh) { + struct zmk_widget_bongo_cat *widget; + struct zmk_position_state_changed *ev = as_zmk_position_state_changed(eh); + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_bongo_state(widget->obj, ev); } + return ZMK_EV_EVENT_BUBBLE; +} + +ZMK_LISTENER(widget_bongo_cat, bongo_cat_listener) +ZMK_SUBSCRIPTION(widget_bongo_cat, zmk_position_state_changed); +#endif /* IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) */ diff --git a/app/src/display/widgets/bongo_img.c b/app/src/display/widgets/bongo_img.c new file mode 100644 index 000000000000..f13e9d5f8f87 --- /dev/null +++ b/app/src/display/widgets/bongo_img.c @@ -0,0 +1,211 @@ +#include + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_LEFT +#define LV_ATTRIBUTE_IMG_LEFT +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_LEFT uint8_t left_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x00, + 0x00, 0x38, 0x80, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x45, 0x00, 0x00, 0x00, 0x0c, 0xc8, 0x00, + 0x00, 0x82, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, + 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, + 0xf0, 0x80, 0x00, 0x48, 0x00, 0x00, 0x10, 0x00, + 0x0f, 0x80, 0x00, 0x31, 0x00, 0x00, 0x10, 0x00, + 0x00, 0xf0, 0x00, 0x06, 0x30, 0x00, 0x20, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x30, 0x00, 0x20, 0x00, + 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0x02, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0xf4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t left = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 60, + .header.h = 31, + .data_size = 256, + .data = left_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_RIGHT +#define LV_ATTRIBUTE_IMG_RIGHT +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_RIGHT uint8_t right_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0xc8, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x20, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, + 0xf0, 0x40, 0x00, 0x48, 0x00, 0x00, 0x10, 0x00, + 0x0f, 0x40, 0x00, 0x31, 0x00, 0x70, 0x10, 0x00, + 0x00, 0x80, 0x20, 0x06, 0x30, 0x88, 0x20, 0x00, + 0x00, 0x80, 0x40, 0x00, 0x31, 0x04, 0x20, 0x00, + 0x01, 0x00, 0xf0, 0x00, 0x01, 0x04, 0x20, 0x00, + 0x01, 0x01, 0x0f, 0x00, 0x01, 0x00, 0x10, 0x00, + 0x01, 0x02, 0x00, 0xf0, 0x01, 0x00, 0x10, 0x00, + 0x00, 0x8c, 0x00, 0x0f, 0x01, 0x00, 0x08, 0x00, + 0x00, 0x70, 0x00, 0x00, 0xf1, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t right = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 60, + .header.h = 31, + .data_size = 256, + .data = right_map, +}; + +#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) +#ifndef LV_ATTRIBUTE_IMG_NONE +#define LV_ATTRIBUTE_IMG_NONE +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_NONE uint8_t none_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x00, + 0x00, 0x38, 0x80, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x45, 0x00, 0x00, 0x00, 0x0c, 0xc8, 0x00, + 0x00, 0x82, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, + 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, + 0xf0, 0x80, 0x00, 0x48, 0x00, 0x00, 0x10, 0x00, + 0x0f, 0x80, 0x00, 0x31, 0x00, 0x70, 0x10, 0x00, + 0x00, 0xf0, 0x00, 0x06, 0x30, 0x88, 0x20, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x31, 0x04, 0x20, 0x00, + 0x00, 0x00, 0xf0, 0x00, 0x01, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t none = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 60, + .header.h = 31, + .data_size = 256, + .data = none_map, +}; + +#ifndef LV_ATTRIBUTE_IMG_BOTH +#define LV_ATTRIBUTE_IMG_BOTH +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BOTH uint8_t both_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0xc8, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x10, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x20, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, + 0xf0, 0x40, 0x00, 0x48, 0x00, 0x00, 0x10, 0x00, + 0x0f, 0x40, 0x00, 0x31, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x80, 0x20, 0x06, 0x30, 0x00, 0x20, 0x00, + 0x00, 0x80, 0x40, 0x00, 0x30, 0x00, 0x20, 0x00, + 0x01, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x01, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x01, 0x02, 0x00, 0xf0, 0x02, 0x00, 0x10, 0x00, + 0x00, 0x8c, 0x00, 0x0f, 0x04, 0x00, 0x08, 0x00, + 0x00, 0x70, 0x00, 0x00, 0xf8, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0xf4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t both = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 60, + .header.h = 31, + .data_size = 256, + .data = both_map, +}; +#endif /* IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) */ From 79bac9d9e4d28abbe45998af8083c7bb1a3233c1 Mon Sep 17 00:00:00 2001 From: down Date: Mon, 6 Jun 2022 13:03:57 +0700 Subject: [PATCH 4/8] feat(widget): bongo cat is now interactive only --- app/include/zmk/display/widgets/bongo_cat.h | 4 +-- app/src/display/widgets/Kconfig | 17 --------- app/src/display/widgets/bongo_cat.c | 38 +++------------------ app/src/display/widgets/bongo_img.c | 2 -- 4 files changed, 6 insertions(+), 55 deletions(-) diff --git a/app/include/zmk/display/widgets/bongo_cat.h b/app/include/zmk/display/widgets/bongo_cat.h index 4465639d3f02..28fb94313752 100644 --- a/app/include/zmk/display/widgets/bongo_cat.h +++ b/app/include/zmk/display/widgets/bongo_cat.h @@ -12,9 +12,7 @@ struct zmk_widget_bongo_cat { sys_snode_t node; lv_obj_t *obj; -#if !IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) - lv_anim_t anim; -#endif + bool is_right; }; int zmk_widget_bongo_cat_init(struct zmk_widget_bongo_cat *widget, lv_obj_t *parent); diff --git a/app/src/display/widgets/Kconfig b/app/src/display/widgets/Kconfig index 49bc46b36178..b8a1e484125a 100644 --- a/app/src/display/widgets/Kconfig +++ b/app/src/display/widgets/Kconfig @@ -38,22 +38,5 @@ config ZMK_WIDGET_BONGO_CAT depends on !ZMK_SPLIT || ZMK_SPLIT_BLE_ROLE_CENTRAL select LVGL_USE_LABEL select LVGL_USE_IMG - select LVGL_USE_ANIMATION if !ZMK_WIDGET_BONGO_CAT_INTERACTIVE - -if ZMK_WIDGET_BONGO_CAT - -config ZMK_WIDGET_BONGO_CAT_INTERACTIVE - bool "Bongo cat responds to key press" - default y - -if !ZMK_WIDGET_BONGO_CAT_INTERACTIVE - -config ZMK_WIDGET_BONGO_CAT_ANIMATION_INTERVAL - int "Time delay in ms for bongo cat animation" - default 531 - -endif - -endif # ZMK_WIDGET_BONGO_CAT endmenu diff --git a/app/src/display/widgets/bongo_cat.c b/app/src/display/widgets/bongo_cat.c index 5d2ef14cc7b9..af88d53a81c5 100644 --- a/app/src/display/widgets/bongo_cat.c +++ b/app/src/display/widgets/bongo_cat.c @@ -10,17 +10,12 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include #include - -#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) #include -#endif static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); LV_IMG_DECLARE(left); LV_IMG_DECLARE(right); - -#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) LV_IMG_DECLARE(none); LV_IMG_DECLARE(both); @@ -36,33 +31,11 @@ const void *images[] = { &right, &both }; -#else -const void *images[] = { - &left, - &right -}; - -void set_bongo_state(void *var, lv_anim_value_t val) { - lv_img_set_src( (lv_obj_t *)var, images[val]); -} -#endif /* IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) */ int zmk_widget_bongo_cat_init(struct zmk_widget_bongo_cat *widget, lv_obj_t *parent) { widget->obj = lv_img_create(parent, NULL); - -#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) lv_img_set_src(widget->obj, &none); current_bongo_state = bongo_state_none; -#else - lv_anim_init(&widget->anim); - lv_anim_set_exec_cb(&widget->anim, (lv_anim_exec_xcb_t) set_bongo_state); - lv_anim_set_var(&widget->anim, widget->obj); - lv_anim_set_time(&widget->anim, CONFIG_ZMK_WIDGET_BONGO_CAT_ANIMATION_INTERVAL); - lv_anim_set_values(&widget->anim, 0, 1); - lv_anim_set_repeat_count(&widget->anim, LV_ANIM_REPEAT_INFINITE); - lv_anim_set_repeat_delay(&widget->anim, CONFIG_ZMK_WIDGET_BONGO_CAT_ANIMATION_INTERVAL); - lv_anim_start(&widget->anim); -#endif /* IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) */ sys_slist_append(&widgets, &widget->node); @@ -73,13 +46,12 @@ lv_obj_t *zmk_widget_bongo_cat_obj(struct zmk_widget_bongo_cat *widget) { return widget->obj; } -#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) -void set_bongo_state(lv_obj_t *img, struct zmk_position_state_changed *ev) { +void set_bongo_state(struct zmk_widget_bongo_cat *widget, struct zmk_position_state_changed *ev) { if (ev == NULL) { return; } - uint8_t tmp = bongo_state_left; + uint8_t tmp = bongo_state_left << widget->is_right; if (ev->state) { if (current_bongo_state & (bongo_state_left | bongo_state_right)) { tmp = bongo_state_left | bongo_state_right; @@ -87,20 +59,20 @@ void set_bongo_state(lv_obj_t *img, struct zmk_position_state_changed *ev) { } else { if (current_bongo_state ^ (bongo_state_left | bongo_state_right)) { tmp = bongo_state_none; + widget->is_right = !widget->is_right; } } current_bongo_state = tmp; - lv_img_set_src(img, images[current_bongo_state]); + lv_img_set_src(widget->obj, images[current_bongo_state]); } int bongo_cat_listener(const zmk_event_t *eh) { struct zmk_widget_bongo_cat *widget; struct zmk_position_state_changed *ev = as_zmk_position_state_changed(eh); - SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_bongo_state(widget->obj, ev); } + SYS_SLIST_FOR_EACH_CONTAINER(&widgets, widget, node) { set_bongo_state(widget, ev); } return ZMK_EV_EVENT_BUBBLE; } ZMK_LISTENER(widget_bongo_cat, bongo_cat_listener) ZMK_SUBSCRIPTION(widget_bongo_cat, zmk_position_state_changed); -#endif /* IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) */ diff --git a/app/src/display/widgets/bongo_img.c b/app/src/display/widgets/bongo_img.c index f13e9d5f8f87..0338421eb00a 100644 --- a/app/src/display/widgets/bongo_img.c +++ b/app/src/display/widgets/bongo_img.c @@ -106,7 +106,6 @@ const lv_img_dsc_t right = { .data = right_map, }; -#if IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) #ifndef LV_ATTRIBUTE_IMG_NONE #define LV_ATTRIBUTE_IMG_NONE #endif @@ -208,4 +207,3 @@ const lv_img_dsc_t both = { .data_size = 256, .data = both_map, }; -#endif /* IS_ENABLED(CONFIG_ZMK_WIDGET_BONGO_CAT_INTERACTIVE) */ From 6e010d111a3e0a0ba04b0d046bee263170af6780 Mon Sep 17 00:00:00 2001 From: down Date: Mon, 6 Jun 2022 13:11:02 +0700 Subject: [PATCH 5/8] fix(widget): reorder code --- app/src/display/widgets/bongo_cat.c | 2 +- app/src/display/widgets/bongo_img.c | 102 ++++++++++++++-------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/app/src/display/widgets/bongo_cat.c b/app/src/display/widgets/bongo_cat.c index af88d53a81c5..5e6acf9d5255 100644 --- a/app/src/display/widgets/bongo_cat.c +++ b/app/src/display/widgets/bongo_cat.c @@ -14,9 +14,9 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); +LV_IMG_DECLARE(none); LV_IMG_DECLARE(left); LV_IMG_DECLARE(right); -LV_IMG_DECLARE(none); LV_IMG_DECLARE(both); enum bongo_state { diff --git a/app/src/display/widgets/bongo_img.c b/app/src/display/widgets/bongo_img.c index 0338421eb00a..942187eaeee4 100644 --- a/app/src/display/widgets/bongo_img.c +++ b/app/src/display/widgets/bongo_img.c @@ -4,6 +4,57 @@ #define LV_ATTRIBUTE_MEM_ALIGN #endif +#ifndef LV_ATTRIBUTE_IMG_NONE +#define LV_ATTRIBUTE_IMG_NONE +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_NONE uint8_t none_map[] = { + 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ + 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ + + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x00, + 0x00, 0x38, 0x80, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x45, 0x00, 0x00, 0x00, 0x0c, 0xc8, 0x00, + 0x00, 0x82, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, + 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, + 0xf0, 0x80, 0x00, 0x48, 0x00, 0x00, 0x10, 0x00, + 0x0f, 0x80, 0x00, 0x31, 0x00, 0x70, 0x10, 0x00, + 0x00, 0xf0, 0x00, 0x06, 0x30, 0x88, 0x20, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x31, 0x04, 0x20, 0x00, + 0x00, 0x00, 0xf0, 0x00, 0x01, 0x04, 0x20, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_img_dsc_t none = { + .header.cf = LV_IMG_CF_INDEXED_1BIT, + .header.always_zero = 0, + .header.reserved = 0, + .header.w = 60, + .header.h = 31, + .data_size = 256, + .data = none_map, +}; + #ifndef LV_ATTRIBUTE_IMG_LEFT #define LV_ATTRIBUTE_IMG_LEFT #endif @@ -106,57 +157,6 @@ const lv_img_dsc_t right = { .data = right_map, }; -#ifndef LV_ATTRIBUTE_IMG_NONE -#define LV_ATTRIBUTE_IMG_NONE -#endif - -const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_NONE uint8_t none_map[] = { - 0xff, 0xff, 0xff, 0xff, /*Color of index 0*/ - 0x00, 0x00, 0x00, 0xff, /*Color of index 1*/ - - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x80, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x00, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x00, - 0x00, 0x38, 0x80, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x45, 0x00, 0x00, 0x00, 0x0c, 0xc8, 0x00, - 0x00, 0x82, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, - 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, - 0xf0, 0x80, 0x00, 0x48, 0x00, 0x00, 0x10, 0x00, - 0x0f, 0x80, 0x00, 0x31, 0x00, 0x70, 0x10, 0x00, - 0x00, 0xf0, 0x00, 0x06, 0x30, 0x88, 0x20, 0x00, - 0x00, 0x0f, 0x00, 0x00, 0x31, 0x04, 0x20, 0x00, - 0x00, 0x00, 0xf0, 0x00, 0x01, 0x04, 0x20, 0x00, - 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -const lv_img_dsc_t none = { - .header.cf = LV_IMG_CF_INDEXED_1BIT, - .header.always_zero = 0, - .header.reserved = 0, - .header.w = 60, - .header.h = 31, - .data_size = 256, - .data = none_map, -}; - #ifndef LV_ATTRIBUTE_IMG_BOTH #define LV_ATTRIBUTE_IMG_BOTH #endif From 1b5e5bb798f7bf3fe0fac504bfa0efddb74705c2 Mon Sep 17 00:00:00 2001 From: down Date: Mon, 6 Jun 2022 13:22:50 +0700 Subject: [PATCH 6/8] fix(widget): reorder code, add comments --- app/src/display/widgets/bongo_cat.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/display/widgets/bongo_cat.c b/app/src/display/widgets/bongo_cat.c index 5e6acf9d5255..60aedc1ae8a4 100644 --- a/app/src/display/widgets/bongo_cat.c +++ b/app/src/display/widgets/bongo_cat.c @@ -14,17 +14,17 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); +enum bongo_state { + bongo_state_none, /* no hands down */ + bongo_state_left, /* left hand down */ + bongo_state_right, /* right hand down */ +} current_bongo_state; + LV_IMG_DECLARE(none); LV_IMG_DECLARE(left); LV_IMG_DECLARE(right); LV_IMG_DECLARE(both); -enum bongo_state { - bongo_state_none, - bongo_state_left, - bongo_state_right, -} current_bongo_state; - const void *images[] = { &none, &left, @@ -59,7 +59,7 @@ void set_bongo_state(struct zmk_widget_bongo_cat *widget, struct zmk_position_st } else { if (current_bongo_state ^ (bongo_state_left | bongo_state_right)) { tmp = bongo_state_none; - widget->is_right = !widget->is_right; + widget->is_right = !widget->is_right; /* flip side when return to none state */ } } From 31678227b911ff54ef3eb9970329aa920a36f773 Mon Sep 17 00:00:00 2001 From: down Date: Sun, 19 Jun 2022 16:18:29 +0700 Subject: [PATCH 7/8] fix(widgets): no need to set the same state --- app/src/display/widgets/bongo_cat.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/display/widgets/bongo_cat.c b/app/src/display/widgets/bongo_cat.c index 60aedc1ae8a4..a911350053ca 100644 --- a/app/src/display/widgets/bongo_cat.c +++ b/app/src/display/widgets/bongo_cat.c @@ -59,10 +59,14 @@ void set_bongo_state(struct zmk_widget_bongo_cat *widget, struct zmk_position_st } else { if (current_bongo_state ^ (bongo_state_left | bongo_state_right)) { tmp = bongo_state_none; - widget->is_right = !widget->is_right; /* flip side when return to none state */ + widget->is_right = !widget->is_right; /* switch hand when return to none state */ } } + if (current_bongo_state == tmp) { + return; + } + current_bongo_state = tmp; lv_img_set_src(widget->obj, images[current_bongo_state]); } From 15b703e1b7db091f103867ecf4b11af2cf444357 Mon Sep 17 00:00:00 2001 From: down Date: Sat, 17 Sep 2022 22:05:18 +0700 Subject: [PATCH 8/8] add license info --- app/src/display/widgets/bongo_img.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/src/display/widgets/bongo_img.c b/app/src/display/widgets/bongo_img.c index 942187eaeee4..f7b3e0325bc2 100644 --- a/app/src/display/widgets/bongo_img.c +++ b/app/src/display/widgets/bongo_img.c @@ -1,3 +1,16 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/* + * This is a pixel redraw of the redraw of the original Bongo Cat + * https://twitter.com/strayrogue/status/992994454058381312 + * The redraw is distributed under CC BY-SA 4.0 + * https://commons.wikimedia.org/wiki/File:Bongo_Cat_Redraw.png + */ + #include #ifndef LV_ATTRIBUTE_MEM_ALIGN