fix: lv_deinit/lv_init crash or hang (#2910)
* Fix themes that are not correctly initialized after lv_deinit * Fix performance & memory monitoring not correctly initialized after lv_deinit & lv_init * Apply code formatting fixes * Fix build errors * Fix build errors * Fix formatting Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
@@ -29,6 +29,23 @@
|
|||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t perf_last_time;
|
||||||
|
uint32_t elaps_sum;
|
||||||
|
uint32_t frame_cnt;
|
||||||
|
uint32_t fps_sum_cnt;
|
||||||
|
uint32_t fps_sum_all;
|
||||||
|
#if LV_USE_LABEL
|
||||||
|
lv_obj_t * perf_label;
|
||||||
|
#endif
|
||||||
|
} perf_monitor_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t mem_last_time;
|
||||||
|
#if LV_USE_LABEL
|
||||||
|
lv_obj_t * mem_label;
|
||||||
|
#endif
|
||||||
|
} mem_monitor_t;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
@@ -43,14 +60,25 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p);
|
|||||||
static void draw_buf_flush(void);
|
static void draw_buf_flush(void);
|
||||||
static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);
|
static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);
|
||||||
|
|
||||||
|
#if LV_USE_PERF_MONITOR
|
||||||
|
static void perf_monitor_init(perf_monitor_t * perf_monitor);
|
||||||
|
#endif
|
||||||
|
#if LV_USE_MEM_MONITOR
|
||||||
|
static void mem_monitor_init(mem_monitor_t * mem_monitor);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
static uint32_t px_num;
|
static uint32_t px_num;
|
||||||
static lv_disp_t * disp_refr; /*Display being refreshed*/
|
static lv_disp_t * disp_refr; /*Display being refreshed*/
|
||||||
|
|
||||||
#if LV_USE_PERF_MONITOR
|
#if LV_USE_PERF_MONITOR
|
||||||
static uint32_t fps_sum_cnt;
|
static perf_monitor_t perf_monitor;
|
||||||
static uint32_t fps_sum_all;
|
#endif
|
||||||
|
|
||||||
|
#if LV_USE_MEM_MONITOR
|
||||||
|
static mem_monitor_t mem_monitor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
@@ -71,7 +99,12 @@ static lv_disp_t * disp_refr; /*Display being refreshed*/
|
|||||||
*/
|
*/
|
||||||
void _lv_refr_init(void)
|
void _lv_refr_init(void)
|
||||||
{
|
{
|
||||||
/*Nothing to do*/
|
#if LV_USE_PERF_MONITOR
|
||||||
|
perf_monitor_init(&perf_monitor);
|
||||||
|
#endif
|
||||||
|
#if LV_USE_MEM_MONITOR
|
||||||
|
mem_monitor_init(&mem_monitor);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -245,7 +278,7 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_PERF_MONITOR && LV_USE_LABEL
|
#if LV_USE_PERF_MONITOR && LV_USE_LABEL
|
||||||
static lv_obj_t * perf_label = NULL;
|
lv_obj_t * perf_label = perf_monitor.perf_label;
|
||||||
if(perf_label == NULL) {
|
if(perf_label == NULL) {
|
||||||
perf_label = lv_label_create(lv_layer_sys());
|
perf_label = lv_label_create(lv_layer_sys());
|
||||||
lv_obj_set_style_bg_opa(perf_label, LV_OPA_50, 0);
|
lv_obj_set_style_bg_opa(perf_label, LV_OPA_50, 0);
|
||||||
@@ -260,36 +293,41 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
|
|||||||
lv_obj_align(perf_label, LV_USE_PERF_MONITOR_POS, 0, 0);
|
lv_obj_align(perf_label, LV_USE_PERF_MONITOR_POS, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t perf_last_time = 0;
|
if(lv_tick_elaps(perf_monitor.perf_last_time) < 300) {
|
||||||
static uint32_t elaps_sum = 0;
|
|
||||||
static uint32_t frame_cnt = 0;
|
|
||||||
if(lv_tick_elaps(perf_last_time) < 300) {
|
|
||||||
if(px_num > 5000) {
|
if(px_num > 5000) {
|
||||||
elaps_sum += elaps;
|
perf_monitor.elaps_sum += elaps;
|
||||||
frame_cnt ++;
|
perf_monitor.frame_cnt ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
perf_last_time = lv_tick_get();
|
perf_monitor.perf_last_time = lv_tick_get();
|
||||||
uint32_t fps_limit = 1000 / disp_refr->refr_timer->period;
|
uint32_t fps_limit = 1000 / disp_refr->refr_timer->period;
|
||||||
uint32_t fps;
|
uint32_t fps;
|
||||||
|
|
||||||
if(elaps_sum == 0) elaps_sum = 1;
|
if(perf_monitor.elaps_sum == 0) {
|
||||||
if(frame_cnt == 0) fps = fps_limit;
|
perf_monitor.elaps_sum = 1;
|
||||||
else fps = (1000 * frame_cnt) / elaps_sum;
|
}
|
||||||
elaps_sum = 0;
|
if(perf_monitor.frame_cnt == 0) {
|
||||||
frame_cnt = 0;
|
fps = fps_limit;
|
||||||
if(fps > fps_limit) fps = fps_limit;
|
}
|
||||||
|
else {
|
||||||
|
fps = (1000 * perf_monitor.frame_cnt) / perf_monitor.elaps_sum;
|
||||||
|
}
|
||||||
|
perf_monitor.elaps_sum = 0;
|
||||||
|
perf_monitor.frame_cnt = 0;
|
||||||
|
if(fps > fps_limit) {
|
||||||
|
fps = fps_limit;
|
||||||
|
}
|
||||||
|
|
||||||
fps_sum_all += fps;
|
perf_monitor.fps_sum_all += fps;
|
||||||
fps_sum_cnt ++;
|
perf_monitor.fps_sum_cnt ++;
|
||||||
uint32_t cpu = 100 - lv_timer_get_idle();
|
uint32_t cpu = 100 - lv_timer_get_idle();
|
||||||
lv_label_set_text_fmt(perf_label, "%"LV_PRIu32" FPS\n%"LV_PRIu32"%% CPU", fps, cpu);
|
lv_label_set_text_fmt(perf_label, "%"LV_PRIu32" FPS\n%"LV_PRIu32"%% CPU", fps, cpu);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LV_USE_MEM_MONITOR && LV_MEM_CUSTOM == 0 && LV_USE_LABEL
|
#if LV_USE_MEM_MONITOR && LV_MEM_CUSTOM == 0 && LV_USE_LABEL
|
||||||
static lv_obj_t * mem_label = NULL;
|
lv_obj_t * mem_label = mem_monitor.mem_label;
|
||||||
if(mem_label == NULL) {
|
if(mem_label == NULL) {
|
||||||
mem_label = lv_label_create(lv_layer_sys());
|
mem_label = lv_label_create(lv_layer_sys());
|
||||||
lv_obj_set_style_bg_opa(mem_label, LV_OPA_50, 0);
|
lv_obj_set_style_bg_opa(mem_label, LV_OPA_50, 0);
|
||||||
@@ -303,9 +341,8 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
|
|||||||
lv_obj_align(mem_label, LV_USE_MEM_MONITOR_POS, 0, 0);
|
lv_obj_align(mem_label, LV_USE_MEM_MONITOR_POS, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t mem_last_time = 0;
|
if(lv_tick_elaps(mem_monitor.mem_last_time) > 300) {
|
||||||
if(lv_tick_elaps(mem_last_time) > 300) {
|
mem_monitor.mem_last_time = lv_tick_get();
|
||||||
mem_last_time = lv_tick_get();
|
|
||||||
lv_mem_monitor_t mon;
|
lv_mem_monitor_t mon;
|
||||||
lv_mem_monitor(&mon);
|
lv_mem_monitor(&mon);
|
||||||
uint32_t used_size = mon.total_size - mon.free_size;;
|
uint32_t used_size = mon.total_size - mon.free_size;;
|
||||||
@@ -323,16 +360,16 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
|
|||||||
#if LV_USE_PERF_MONITOR
|
#if LV_USE_PERF_MONITOR
|
||||||
void lv_refr_reset_fps_counter(void)
|
void lv_refr_reset_fps_counter(void)
|
||||||
{
|
{
|
||||||
fps_sum_all = 0;
|
perf_monitor.fps_sum_all = 0;
|
||||||
fps_sum_cnt = 0;
|
perf_monitor.fps_sum_cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t lv_refr_get_fps_avg(void)
|
uint32_t lv_refr_get_fps_avg(void)
|
||||||
{
|
{
|
||||||
if(fps_sum_cnt == 0)
|
if(perf_monitor.fps_sum_cnt == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
return fps_sum_all / fps_sum_cnt;
|
return perf_monitor.fps_sum_all / perf_monitor.fps_sum_cnt;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1002,3 +1039,26 @@ static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_
|
|||||||
|
|
||||||
drv->flush_cb(drv, &offset_area, color_p);
|
drv->flush_cb(drv, &offset_area, color_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LV_USE_PERF_MONITOR
|
||||||
|
static void perf_monitor_init(perf_monitor_t * _perf_monitor)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(_perf_monitor);
|
||||||
|
_perf_monitor->elaps_sum = 0;
|
||||||
|
_perf_monitor->fps_sum_all = 0;
|
||||||
|
_perf_monitor->fps_sum_cnt = 0;
|
||||||
|
_perf_monitor->frame_cnt = 0;
|
||||||
|
_perf_monitor->perf_last_time = 0;
|
||||||
|
_perf_monitor->perf_label = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LV_USE_MEM_MONITOR
|
||||||
|
static void mem_monitor_init(mem_monitor_t * _mem_monitor)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(_mem_monitor);
|
||||||
|
_mem_monitor->mem_last_time = 0;
|
||||||
|
_mem_monitor->mem_label = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj);
|
|||||||
**********************/
|
**********************/
|
||||||
static my_theme_styles_t * styles;
|
static my_theme_styles_t * styles;
|
||||||
static lv_theme_t theme;
|
static lv_theme_t theme;
|
||||||
static bool inited;
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
@@ -120,13 +119,18 @@ static void style_init(void)
|
|||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
bool lv_theme_basic_is_inited(void)
|
||||||
|
{
|
||||||
|
return LV_GC_ROOT(_lv_theme_default_styles) == NULL ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
lv_theme_t * lv_theme_basic_init(lv_disp_t * disp)
|
lv_theme_t * lv_theme_basic_init(lv_disp_t * disp)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*This trick is required only to avoid the garbage collection of
|
/*This trick is required only to avoid the garbage collection of
|
||||||
*styles' data if LVGL is used in a binding (e.g. Micropython)
|
*styles' data if LVGL is used in a binding (e.g. Micropython)
|
||||||
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
|
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
|
||||||
if(!inited) {
|
if(!lv_theme_basic_is_inited()) {
|
||||||
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
|
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
|
||||||
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
|
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
|
||||||
}
|
}
|
||||||
@@ -139,9 +143,9 @@ lv_theme_t * lv_theme_basic_init(lv_disp_t * disp)
|
|||||||
|
|
||||||
style_init();
|
style_init();
|
||||||
|
|
||||||
inited = true;
|
if(disp == NULL || lv_disp_get_theme(disp) == &theme) {
|
||||||
|
lv_obj_report_style_change(NULL);
|
||||||
if(disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL);
|
}
|
||||||
|
|
||||||
return (lv_theme_t *)&theme;
|
return (lv_theme_t *)&theme;
|
||||||
}
|
}
|
||||||
@@ -375,8 +379,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
|||||||
|
|
||||||
static void style_init_reset(lv_style_t * style)
|
static void style_init_reset(lv_style_t * style)
|
||||||
{
|
{
|
||||||
if(inited) lv_style_reset(style);
|
if(lv_theme_basic_is_inited()) {
|
||||||
else lv_style_init(style);
|
lv_style_reset(style);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lv_style_init(style);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -36,6 +36,12 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
lv_theme_t * lv_theme_basic_init(lv_disp_t * disp);
|
lv_theme_t * lv_theme_basic_init(lv_disp_t * disp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the theme is initialized
|
||||||
|
* @return true if default theme is initialized, false otherwise
|
||||||
|
*/
|
||||||
|
bool lv_theme_basic_is_inited(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -173,7 +173,6 @@ static void style_init_reset(lv_style_t * style);
|
|||||||
static my_theme_styles_t * styles;
|
static my_theme_styles_t * styles;
|
||||||
static lv_theme_t theme;
|
static lv_theme_t theme;
|
||||||
static disp_size_t disp_size;
|
static disp_size_t disp_size;
|
||||||
static bool inited;
|
|
||||||
static lv_color_t color_scr;
|
static lv_color_t color_scr;
|
||||||
static lv_color_t color_text;
|
static lv_color_t color_text;
|
||||||
static lv_color_t color_card;
|
static lv_color_t color_card;
|
||||||
@@ -647,7 +646,7 @@ lv_theme_t * lv_theme_default_init(lv_disp_t * disp, lv_color_t color_primary, l
|
|||||||
/*This trick is required only to avoid the garbage collection of
|
/*This trick is required only to avoid the garbage collection of
|
||||||
*styles' data if LVGL is used in a binding (e.g. Micropython)
|
*styles' data if LVGL is used in a binding (e.g. Micropython)
|
||||||
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
|
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
|
||||||
if(!inited) {
|
if(!lv_theme_default_is_inited()) {
|
||||||
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
|
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
|
||||||
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
|
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
|
||||||
}
|
}
|
||||||
@@ -667,8 +666,6 @@ lv_theme_t * lv_theme_default_init(lv_disp_t * disp, lv_color_t color_primary, l
|
|||||||
|
|
||||||
style_init();
|
style_init();
|
||||||
|
|
||||||
inited = true;
|
|
||||||
|
|
||||||
if(disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL);
|
if(disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL);
|
||||||
|
|
||||||
return (lv_theme_t *)&theme;
|
return (lv_theme_t *)&theme;
|
||||||
@@ -676,14 +673,16 @@ lv_theme_t * lv_theme_default_init(lv_disp_t * disp, lv_color_t color_primary, l
|
|||||||
|
|
||||||
lv_theme_t * lv_theme_default_get(void)
|
lv_theme_t * lv_theme_default_get(void)
|
||||||
{
|
{
|
||||||
if(!inited) return NULL;
|
if(!lv_theme_default_is_inited()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return (lv_theme_t *)&theme;
|
return (lv_theme_t *)&theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lv_theme_default_is_inited(void)
|
bool lv_theme_default_is_inited(void)
|
||||||
{
|
{
|
||||||
return inited;
|
return LV_GC_ROOT(_lv_theme_default_styles) == NULL ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1161,8 +1160,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
|||||||
|
|
||||||
static void style_init_reset(lv_style_t * style)
|
static void style_init_reset(lv_style_t * style)
|
||||||
{
|
{
|
||||||
if(inited) lv_style_reset(style);
|
if(lv_theme_default_is_inited()) {
|
||||||
else lv_style_init(style);
|
lv_style_reset(style);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lv_style_init(style);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj);
|
|||||||
**********************/
|
**********************/
|
||||||
static my_theme_styles_t * styles;
|
static my_theme_styles_t * styles;
|
||||||
static lv_theme_t theme;
|
static lv_theme_t theme;
|
||||||
static bool inited;
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
@@ -164,13 +163,18 @@ static void style_init(bool dark_bg, const lv_font_t * font)
|
|||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
bool lv_theme_mono_is_inited(void)
|
||||||
|
{
|
||||||
|
return LV_GC_ROOT(_lv_theme_default_styles) == NULL ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t * font)
|
lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t * font)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*This trick is required only to avoid the garbage collection of
|
/*This trick is required only to avoid the garbage collection of
|
||||||
*styles' data if LVGL is used in a binding (e.g. Micropython)
|
*styles' data if LVGL is used in a binding (e.g. Micropython)
|
||||||
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
|
*In a general case styles could be in simple `static lv_style_t my_style...` variables*/
|
||||||
if(!inited) {
|
if(!lv_theme_mono_is_inited()) {
|
||||||
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
|
LV_GC_ROOT(_lv_theme_default_styles) = lv_mem_alloc(sizeof(my_theme_styles_t));
|
||||||
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
|
styles = (my_theme_styles_t *)LV_GC_ROOT(_lv_theme_default_styles);
|
||||||
}
|
}
|
||||||
@@ -183,8 +187,6 @@ lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t
|
|||||||
|
|
||||||
style_init(dark_bg, font);
|
style_init(dark_bg, font);
|
||||||
|
|
||||||
inited = true;
|
|
||||||
|
|
||||||
if(disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL);
|
if(disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL);
|
||||||
|
|
||||||
return (lv_theme_t *)&theme;
|
return (lv_theme_t *)&theme;
|
||||||
@@ -487,8 +489,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
|||||||
|
|
||||||
static void style_init_reset(lv_style_t * style)
|
static void style_init_reset(lv_style_t * style)
|
||||||
{
|
{
|
||||||
if(inited) lv_style_reset(style);
|
if(lv_theme_mono_is_inited()) {
|
||||||
else lv_style_init(style);
|
lv_style_reset(style);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lv_style_init(style);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t * font);
|
lv_theme_t * lv_theme_mono_init(lv_disp_t * disp, bool dark_bg, const lv_font_t * font);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the theme is initialized
|
||||||
|
* @return true if default theme is initialized, false otherwise
|
||||||
|
*/
|
||||||
|
bool lv_theme_mono_is_inited(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
Reference in New Issue
Block a user