mirror of
https://gitee.com/jiuyilian/embedded-framework.git
synced 2025-01-06 10:16:51 -05:00
Add lvgl simulator.
This commit is contained in:
parent
3dc608da22
commit
2d74fe6e19
44
external/lvgl_simulator/CMakeLists.txt
vendored
Normal file
44
external/lvgl_simulator/CMakeLists.txt
vendored
Normal file
|
@ -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()
|
||||||
|
|
32
external/lvgl_simulator/README.md
vendored
Normal file
32
external/lvgl_simulator/README.md
vendored
Normal file
|
@ -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代码;
|
223
external/lvgl_simulator/modify/lvgl_main.c
vendored
Normal file
223
external/lvgl_simulator/modify/lvgl_main.c
vendored
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#define _DEFAULT_SOURCE /* needed for usleep() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#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;
|
||||||
|
}
|
11
external/lvgl_simulator/modify/lvgl_main.h
vendored
Normal file
11
external/lvgl_simulator/modify/lvgl_main.h
vendored
Normal file
|
@ -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
|
416
external/lvgl_simulator/modify/monitor.c
vendored
Normal file
416
external/lvgl_simulator/modify/monitor.c
vendored
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
/**
|
||||||
|
* @file monitor.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "monitor.h"
|
||||||
|
#if USE_MONITOR
|
||||||
|
|
||||||
|
#ifndef MONITOR_SDL_INCLUDE_PATH
|
||||||
|
# define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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*/
|
Loading…
Reference in New Issue
Block a user