diff --git a/external/lvgl_simulator/CMakeLists.txt b/external/lvgl_simulator/CMakeLists.txt new file mode 100644 index 00000000..ff5247af --- /dev/null +++ b/external/lvgl_simulator/CMakeLists.txt @@ -0,0 +1,44 @@ + +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) +set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) + +include_directories( + ./lv_sim_vscode_sdl/ + ./lv_sim_vscode_sdl/ui/simulator/inc/ + ./lv_sim_vscode_sdl/lvgl/ + ./modify/ + ./lv_sim_vscode_sdl/lv_drivers/display +) +#do not rely on any other library +#link_directories( +#) + +set(CMAKE_C_FLAGS "-Wall -Wextra -Wshadow -Wundef -Wmaybe-uninitialized -Wmissing-prototypes -Wno-discarded-qualifiers \ +-Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith -fno-strict-aliasing -Wno-error=cpp -Wuninitialized \ +-Wno-unused-parameter -Wno-missing-field-initializers -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default \ +-Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion \ +-Wclobbered -Wdeprecated -Wempty-body -Wshift-negative-value -Wstack-usage=2048 -Wtype-limits -Wsizeof-pointer-memaccess -Wpointer-arith ") +set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wshadow -Wundef -Wmaybe-uninitialized -Wmissing-prototypes -Wno-discarded-qualifiers \ +-Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith -fno-strict-aliasing -Wno-error=cpp -Wuninitialized \ +-Wno-unused-parameter -Wno-missing-field-initializers -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default \ +-Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion \ +-Wclobbered -Wdeprecated -Wempty-body -Wshift-negative-value -Wstack-usage=2048 -Wtype-limits -Wsizeof-pointer-memaccess -Wpointer-arith ") + +add_definitions(-DSIMULATOR=1) +add_definitions(-DLV_BUILD_TEST=0) +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +file(GLOB_RECURSE SRC_FILES_CPP *.cpp) +file(GLOB_RECURSE SRC_FILES *.c) +# add_definitions("-fexceptions") +# add_definitions("-std=c++11") + +set(TARGET_NAME lvglSimulator) +add_library(${TARGET_NAME} STATIC ${SRC_FILES} ${SRC_FILES_CPP}) + +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + target_link_libraries(${TARGET_NAME} SDL2 m) +endif() + diff --git a/external/lvgl_simulator/README.md b/external/lvgl_simulator/README.md new file mode 100644 index 00000000..347a9684 --- /dev/null +++ b/external/lvgl_simulator/README.md @@ -0,0 +1,32 @@ +# 1. lvgl开源库PC模拟器 +## 1.1. 官方git仓库: +``` +git clone --recursive https://github.com/lvgl/lv_sim_vscode_sdl; +``` +注:项目把官方开源代码上传到gitee,方便自主管理。 +## 1.2. 开发环境 +安装Linux支持环境SDL:未安装可能会提示找不到“SDL”相关资源 +``` +sudo apt-get update +sudo apt-get install -y build-essential libsdl2-dev +``` +## 1.3. 修改内容 +1. 自研模块自动关联开源库并使用CMakeList.txt编译; + +## 1.4. 更新 +1.更新了lvgl源码版本(8.3.9)覆盖lv_sim_vscode_sdl/lvgl; +2.修改./lv_sim_vscode_sdl/lv_conf.h,增加下述代码: +``` +// ================== Added by fancy code ================== start +/*BMP decoder library*/ +#define LV_USE_BMP 1 // Use bmp picture. +/*API for open, read, etc*/ +#define LV_USE_FS_POSIX 1 +#if LV_USE_FS_POSIX + #define LV_FS_POSIX_LETTER 'A' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif +// ================== Added by fancy code ================== finish +``` +3.删掉模拟器的example代码; diff --git a/external/lvgl_simulator/modify/lvgl_main.c b/external/lvgl_simulator/modify/lvgl_main.c new file mode 100644 index 00000000..7b740f33 --- /dev/null +++ b/external/lvgl_simulator/modify/lvgl_main.c @@ -0,0 +1,223 @@ + +/********************* + * INCLUDES + *********************/ +#define _DEFAULT_SOURCE /* needed for usleep() */ +#include +#include +#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/ +#include +#include "lvgl/lvgl.h" +#include "lvgl_main.h" +#include "lvgl/examples/lv_examples.h" +// #include "lv_examples/lv_demo.h" +#include "lv_drivers/display/monitor.h" +#include "lv_drivers/indev/mouse.h" +#include "lv_drivers/indev/keyboard.h" +#include "lv_drivers/indev/mousewheel.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void hal_init(const int monitor_hor_res, const int monitor_ver_res); +static int tick_thread(void *data); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * VARIABLES + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +const int LVGL_RUNING = 1; +const int LVGL_EXIT = 0; +int lvglRuning = 0; +int MonitorWidth = 240; +int MonitorHeight = 360; +int mainTest(const unsigned int width, const unsigned int height, void (*appInit)()) +{ + // (void)argc; /*Unused*/ + // (void)argv; /*Unused*/ + const int IS_INIT = 1; + const int IS_NOT_INIT = 0; + static int isInit = IS_NOT_INIT; + if (IS_INIT == isInit) + { + return 0; + } + MonitorWidth = width; // for monitor.c + MonitorHeight = height; // for monitor.c + isInit = IS_INIT; + /*Initialize LVGL*/ + lv_init(); + + /*Initialize the HAL (display, input devices, tick) for LVGL*/ + hal_init(width, height); + + // lv_example_switch_1(); + // lv_example_calendar_1(); + // lv_example_btnmatrix_2(); + // lv_example_checkbox_1(); + // lv_example_colorwheel_1(); + // lv_example_chart_6(); + // lv_example_table_2(); + // lv_example_scroll_2(); + // lv_example_textarea_1(); + // lv_example_msgbox_1(); + // lv_example_dropdown_2(); + // lv_example_btn_1(); + // lv_example_scroll_1(); + // lv_example_tabview_1(); + // lv_example_tabview_1(); + // lv_example_flex_3(); + // lv_example_label_1(); + + // lv_demo_widgets(); + if (appInit) + { + printf("lvgl simulatr init app.\n"); + appInit(); + } + // lv_demo_keypad_encoder(); + // lv_demo_benchmark(); + // lv_demo_stress(); + // lv_demo_music(); + lvglRuning = LVGL_RUNING; + while (lvglRuning) + { + /* Periodically call the lv_task handler. + * It could be done in a timer interrupt or an OS task too.*/ + lv_timer_handler(); + usleep(5 * 1000); + } + lv_deinit(); + return 0; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Initialize the Hardware Abstraction Layer (HAL) for the LVGL graphics + * library + */ +static void hal_init(const int monitor_hor_res, const int monitor_ver_res) +{ + /* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/ + monitor_init(); + /* Tick init. + * You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about + * how much time were elapsed Create an SDL thread to do this*/ + SDL_CreateThread(tick_thread, "tick", NULL); + + /*Create a display buffer*/ + static lv_disp_draw_buf_t disp_buf1; + // static lv_color_t buf1_1[monitor_hor_res * 100]; + // static lv_color_t buf1_2[monitor_hor_res * 100]; + static lv_color_t *buf1_1 = NULL; + static lv_color_t *buf1_2 = NULL; + buf1_1 = (lv_color_t *)malloc(sizeof(lv_color_t) * monitor_hor_res * 100); + buf1_2 = (lv_color_t *)malloc(sizeof(lv_color_t) * monitor_hor_res * 100); + lv_disp_draw_buf_init(&disp_buf1, buf1_1, buf1_2, monitor_hor_res * 100); + + /*Create a display*/ + static lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + disp_drv.draw_buf = &disp_buf1; + disp_drv.flush_cb = monitor_flush; + disp_drv.hor_res = monitor_hor_res; + disp_drv.ver_res = monitor_ver_res; + disp_drv.antialiasing = 1; + + lv_disp_t *disp = lv_disp_drv_register(&disp_drv); + + lv_theme_t *th = lv_theme_default_init(disp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), LV_THEME_DEFAULT_DARK, LV_FONT_DEFAULT); + lv_disp_set_theme(disp, th); + + lv_group_t *g = lv_group_create(); + lv_group_set_default(g); + + /* Add the mouse as input device + * Use the 'mouse' driver which reads the PC's mouse*/ + mouse_init(); + static lv_indev_drv_t indev_drv_1; + lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/ + indev_drv_1.type = LV_INDEV_TYPE_POINTER; + + /*This function will be called periodically (by the library) to get the mouse position and state*/ + indev_drv_1.read_cb = mouse_read; + lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1); + + keyboard_init(); + static lv_indev_drv_t indev_drv_2; + lv_indev_drv_init(&indev_drv_2); /*Basic initialization*/ + indev_drv_2.type = LV_INDEV_TYPE_KEYPAD; + indev_drv_2.read_cb = keyboard_read; + lv_indev_t *kb_indev = lv_indev_drv_register(&indev_drv_2); + lv_indev_set_group(kb_indev, g); + mousewheel_init(); + static lv_indev_drv_t indev_drv_3; + lv_indev_drv_init(&indev_drv_3); /*Basic initialization*/ + indev_drv_3.type = LV_INDEV_TYPE_ENCODER; + indev_drv_3.read_cb = mousewheel_read; + + lv_indev_t *enc_indev = lv_indev_drv_register(&indev_drv_3); + lv_indev_set_group(enc_indev, g); + + /*Set a cursor for the mouse*/ + LV_IMG_DECLARE(mouse_cursor_icon); /*Declare the image file.*/ + lv_obj_t *cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */ + lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/ + lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/ +} + +/** + * A task to measure the elapsed time for LVGL + * @param data unused + * @return never return + */ +static int tick_thread(void *data) +{ + (void)data; + + while (1) + { + SDL_Delay(5); + lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/ + } + + return 0; +} diff --git a/external/lvgl_simulator/modify/lvgl_main.h b/external/lvgl_simulator/modify/lvgl_main.h new file mode 100644 index 00000000..671d4e89 --- /dev/null +++ b/external/lvgl_simulator/modify/lvgl_main.h @@ -0,0 +1,11 @@ +#ifndef LVGL_MAIN_H +#define LVGL_MAIN_H +#ifdef __cplusplus +extern "C" +{ +#endif + int mainTest(const unsigned int width, const unsigned int height, void (*appInit)()); +#ifdef __cplusplus +} +#endif +#endif // !LVGL_MAIN_H \ No newline at end of file diff --git a/external/lvgl_simulator/modify/monitor.c b/external/lvgl_simulator/modify/monitor.c new file mode 100644 index 00000000..38172888 --- /dev/null +++ b/external/lvgl_simulator/modify/monitor.c @@ -0,0 +1,416 @@ +/** + * @file monitor.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "monitor.h" +#if USE_MONITOR + +#ifndef MONITOR_SDL_INCLUDE_PATH +# define MONITOR_SDL_INCLUDE_PATH +#endif + +#include +#include +#include +#include MONITOR_SDL_INCLUDE_PATH +#include "../indev/mouse.h" +#include "../indev/keyboard.h" +#include "../indev/mousewheel.h" + +/********************* + * DEFINES + *********************/ +#define SDL_REFR_PERIOD 50 /*ms*/ + +#ifndef MONITOR_ZOOM +#define MONITOR_ZOOM 1 +#endif +// ====================== add by xiao ==================== +extern int MonitorWidth; +extern int MonitorHeight; +static int GetMonitorWidth(void) +{ + return MonitorWidth; +} +static int GetMonitorHeight(void) +{ + return MonitorHeight; +} +#undef MONITOR_HOR_RES +#ifndef MONITOR_HOR_RES +#define MONITOR_HOR_RES GetMonitorWidth() +#endif + +#undef MONITOR_VER_RES +#ifndef MONITOR_VER_RES +#define MONITOR_VER_RES GetMonitorHeight() +#endif +// ====================== add by xiao ==================== + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + SDL_Window * window; + SDL_Renderer * renderer; + SDL_Texture * texture; + volatile bool sdl_refr_qry; +#if MONITOR_DOUBLE_BUFFERED + uint32_t * tft_fb_act; +#else + uint32_t * tft_fb; +#endif +}monitor_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void window_create(monitor_t * m); +static void window_update(monitor_t * m); +int quit_filter(void * userdata, SDL_Event * event); +static void monitor_sdl_clean_up(void); +static void monitor_sdl_init(void); +static void sdl_event_handler(lv_timer_t * t); +static void monitor_sdl_refr(lv_timer_t * t); + +/*********************** + * GLOBAL PROTOTYPES + ***********************/ + +/********************** + * STATIC VARIABLES + **********************/ +monitor_t monitor; + +#if MONITOR_DUAL +monitor_t monitor2; +#endif + +static volatile bool sdl_inited = false; +static volatile bool sdl_quit_qry = false; + + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Initialize the monitor + */ +void monitor_init(void) +{ + monitor_sdl_init(); + lv_timer_create(sdl_event_handler, 10, NULL); +} + +/** + * @brief + * Added by xiaojiazhu + */ +// void monitor_uninit(void) +// { +// monitor_sdl_clean_up(); +// if (monitor.tft_fb) +// { +// printf("ssssssssssssssssssssssssssssss\n"); +// free(monitor.tft_fb); +// monitor.tft_fb = NULL; +// } +// } + +/** + * Flush a buffer to the marked area + * @param drv pointer to driver where this function belongs + * @param area an area where to copy `color_p` + * @param color_p an array of pixel to copy to the `area` part of the screen + */ +void monitor_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) +{ + lv_coord_t hres = disp_drv->hor_res; + lv_coord_t vres = disp_drv->ver_res; + +// printf("x1:%d,y1:%d,x2:%d,y2:%d\n", area->x1, area->y1, area->x2, area->y2); + + /*Return if the area is out the screen*/ + if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) { + lv_disp_flush_ready(disp_drv); + return; + } + +#if MONITOR_DOUBLE_BUFFERED + monitor.tft_fb_act = (uint32_t *)color_p; +#else /*MONITOR_DOUBLE_BUFFERED*/ + + int32_t y; +#if LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32 /*32 is valid but support 24 for backward compatibility too*/ + int32_t x; + for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) { + for(x = area->x1; x <= area->x2; x++) { + monitor.tft_fb[y * disp_drv->hor_res + x] = lv_color_to32(*color_p); + color_p++; + } + + } +#else + uint32_t w = lv_area_get_width(area); + for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) { + memcpy(&monitor.tft_fb[y * MONITOR_HOR_RES + area->x1], color_p, w * sizeof(lv_color_t)); + color_p += w; + } +#endif +#endif /*MONITOR_DOUBLE_BUFFERED*/ + + monitor.sdl_refr_qry = true; + + /* TYPICALLY YOU DO NOT NEED THIS + * If it was the last part to refresh update the texture of the window.*/ + if(lv_disp_flush_is_last(disp_drv)) { + monitor_sdl_refr(NULL); + } + + /*IMPORTANT! It must be called to tell the system the flush is ready*/ + lv_disp_flush_ready(disp_drv); + +} + + +#if MONITOR_DUAL + +/** + * Flush a buffer to the marked area + * @param drv pointer to driver where this function belongs + * @param area an area where to copy `color_p` + * @param color_p an array of pixel to copy to the `area` part of the screen + */ +void monitor_flush2(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) +{ + lv_coord_t hres = disp_drv->hor_res; + lv_coord_t vres = disp_drv->ver_res; + + /*Return if the area is out the screen*/ + if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) { + lv_disp_flush_ready(disp_drv); + return; + } + +#if MONITOR_DOUBLE_BUFFERED + monitor2.tft_fb_act = (uint32_t *)color_p; + + monitor2.sdl_refr_qry = true; + + /*IMPORTANT! It must be called to tell the system the flush is ready*/ + lv_disp_flush_ready(disp_drv); +#else + + int32_t y; +#if LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32 /*32 is valid but support 24 for backward compatibility too*/ + int32_t x; + for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) { + for(x = area->x1; x <= area->x2; x++) { + monitor2.tft_fb[y * disp_drv->hor_res + x] = lv_color_to32(*color_p); + color_p++; + } + + } +#else + uint32_t w = lv_area_get_width(area); + for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) { + memcpy(&monitor2.tft_fb[y * disp_drv->hor_res + area->x1], color_p, w * sizeof(lv_color_t)); + color_p += w; + } +#endif + + monitor2.sdl_refr_qry = true; + + /* TYPICALLY YOU DO NOT NEED THIS + * If it was the last part to refresh update the texture of the window.*/ + if(lv_disp_flush_is_last(disp_drv)) { + monitor_sdl_refr(NULL); + } + + /*IMPORTANT! It must be called to tell the system the flush is ready*/ + lv_disp_flush_ready(disp_drv); +#endif +} +#endif + +/********************** + * STATIC FUNCTIONS + **********************/ + + +/** + * SDL main thread. All SDL related task have to be handled here! + * It initializes SDL, handles drawing and the mouse. + */ + +static void sdl_event_handler(lv_timer_t * t) +{ + (void)t; + + /*Refresh handling*/ + SDL_Event event; + while(SDL_PollEvent(&event)) { +#if USE_MOUSE != 0 + mouse_handler(&event); +#endif + +#if USE_MOUSEWHEEL != 0 + mousewheel_handler(&event); +#endif + +#if USE_KEYBOARD + keyboard_handler(&event); +#endif + if((&event)->type == SDL_WINDOWEVENT) { + switch((&event)->window.event) { +#if SDL_VERSION_ATLEAST(2, 0, 5) + case SDL_WINDOWEVENT_TAKE_FOCUS: +#endif + case SDL_WINDOWEVENT_EXPOSED: + window_update(&monitor); +#if MONITOR_DUAL + window_update(&monitor2); +#endif + break; + default: + break; + } + } + } + + /*Run until quit event not arrives*/ + if(sdl_quit_qry) { + monitor_sdl_clean_up(); + exit(0); + } +} + +/** + * SDL main thread. All SDL related task have to be handled here! + * It initializes SDL, handles drawing and the mouse. + */ + +static void monitor_sdl_refr(lv_timer_t * t) +{ + (void)t; + + /*Refresh handling*/ + if(monitor.sdl_refr_qry != false) { + monitor.sdl_refr_qry = false; + window_update(&monitor); + } + +#if MONITOR_DUAL + if(monitor2.sdl_refr_qry != false) { + monitor2.sdl_refr_qry = false; + window_update(&monitor2); + } +#endif +} + +int quit_filter(void * userdata, SDL_Event * event) +{ + (void)userdata; + + if(event->type == SDL_WINDOWEVENT) { + if(event->window.event == SDL_WINDOWEVENT_CLOSE) { + sdl_quit_qry = true; + } + } + else if(event->type == SDL_QUIT) { + sdl_quit_qry = true; + } + + return 1; +} + +static void monitor_sdl_clean_up(void) +{ + SDL_DestroyTexture(monitor.texture); + SDL_DestroyRenderer(monitor.renderer); + SDL_DestroyWindow(monitor.window); + +#if MONITOR_DUAL + SDL_DestroyTexture(monitor2.texture); + SDL_DestroyRenderer(monitor2.renderer); + SDL_DestroyWindow(monitor2.window); + +#endif + + SDL_Quit(); +} + +static void monitor_sdl_init(void) +{ + /*Initialize the SDL*/ + SDL_Init(SDL_INIT_VIDEO); + + SDL_SetEventFilter(quit_filter, NULL); + + window_create(&monitor); +#if MONITOR_DUAL + window_create(&monitor2); + int x, y; + SDL_GetWindowPosition(monitor2.window, &x, &y); + SDL_SetWindowPosition(monitor.window, x + (MONITOR_HOR_RES * MONITOR_ZOOM) / 2 + 10, y); + SDL_SetWindowPosition(monitor2.window, x - (MONITOR_HOR_RES * MONITOR_ZOOM) / 2 - 10, y); +#endif + + sdl_inited = true; +} + + +static void window_create(monitor_t * m) +{ + m->window = SDL_CreateWindow("TFT Simulator", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + MONITOR_HOR_RES * MONITOR_ZOOM, MONITOR_VER_RES * MONITOR_ZOOM, 0); /*last param. SDL_WINDOW_BORDERLESS to hide borders*/ + + m->renderer = SDL_CreateRenderer(m->window, -1, SDL_RENDERER_SOFTWARE); + m->texture = SDL_CreateTexture(m->renderer, + SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, MONITOR_HOR_RES, MONITOR_VER_RES); + SDL_SetTextureBlendMode(m->texture, SDL_BLENDMODE_BLEND); + + /*Initialize the frame buffer to gray (77 is an empirical value) */ +#if MONITOR_DOUBLE_BUFFERED + SDL_UpdateTexture(m->texture, NULL, m->tft_fb_act, MONITOR_HOR_RES * sizeof(uint32_t)); +#else + m->tft_fb = (uint32_t *)malloc(sizeof(uint32_t) * MONITOR_HOR_RES * MONITOR_VER_RES); + memset(m->tft_fb, 0x44, MONITOR_HOR_RES * MONITOR_VER_RES * sizeof(uint32_t)); +#endif + + m->sdl_refr_qry = true; + +} + +static void window_update(monitor_t * m) +{ +#if MONITOR_DOUBLE_BUFFERED == 0 + SDL_UpdateTexture(m->texture, NULL, m->tft_fb, MONITOR_HOR_RES * sizeof(uint32_t)); +#else + if(m->tft_fb_act == NULL) return; + SDL_UpdateTexture(m->texture, NULL, m->tft_fb_act, MONITOR_HOR_RES * sizeof(uint32_t)); +#endif + SDL_RenderClear(m->renderer); +#if LV_COLOR_SCREEN_TRANSP + SDL_SetRenderDrawColor(m->renderer, 0xff, 0, 0, 0xff); + SDL_Rect r; + r.x = 0; r.y = 0; r.w = MONITOR_HOR_RES; r.w = MONITOR_VER_RES; + SDL_RenderDrawRect(m->renderer, &r); +#endif + + /*Update the renderer with the texture containing the rendered image*/ + SDL_RenderCopy(m->renderer, m->texture, NULL, NULL); + SDL_RenderPresent(m->renderer); +} + +#endif /*USE_MONITOR*/