Init
This commit is contained in:
47
inc/lvgl/src/debugging/test/lv_test.h
Normal file
47
inc/lvgl/src/debugging/test/lv_test.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file lv_test.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TEST_H
|
||||
#define LV_TEST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#include "lv_test_indev.h"
|
||||
#include "lv_test_display.h"
|
||||
#include "lv_test_fs.h"
|
||||
#include "lv_test_helpers.h"
|
||||
#include "lv_test_screenshot_compare.h"
|
||||
#include "lv_test_indev_gesture.h"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE TEST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEST_H*/
|
||||
108
inc/lvgl/src/debugging/test/lv_test_display.c
Normal file
108
inc/lvgl/src/debugging/test/lv_test_display.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @file lv_test_display.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_test_display.h"
|
||||
#if LV_USE_TEST
|
||||
|
||||
#include "../../core/lv_global.h"
|
||||
#include "../../lvgl_private.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void dummy_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p);
|
||||
|
||||
static void buf_changed_event_cb(lv_event_t * e);
|
||||
static void delete_event_cb(lv_event_t * e);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#define _state LV_GLOBAL_DEFAULT()->test_state
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_display_t * lv_test_display_create(int32_t hor_res, int32_t ver_res)
|
||||
{
|
||||
|
||||
lv_display_t * disp = lv_display_create(hor_res, ver_res);
|
||||
lv_display_set_color_format(disp, LV_COLOR_FORMAT_XRGB8888);
|
||||
|
||||
size_t buf_size = 4 * (hor_res + LV_DRAW_BUF_STRIDE_ALIGN - 1) * ver_res + LV_DRAW_BUF_ALIGN;
|
||||
uint8_t * buf = malloc(buf_size);
|
||||
LV_ASSERT_MALLOC(buf);
|
||||
|
||||
lv_draw_buf_init(&_state.draw_buf, hor_res, ver_res, LV_COLOR_FORMAT_XRGB8888, LV_STRIDE_AUTO, lv_draw_buf_align(buf,
|
||||
LV_COLOR_FORMAT_XRGB8888), buf_size);
|
||||
_state.draw_buf.unaligned_data = buf;
|
||||
lv_display_set_draw_buffers(disp, &_state.draw_buf, NULL);
|
||||
lv_display_set_render_mode(disp, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
|
||||
lv_display_set_flush_cb(disp, dummy_flush_cb);
|
||||
|
||||
lv_display_add_event_cb(disp, buf_changed_event_cb, LV_EVENT_COLOR_FORMAT_CHANGED, NULL);
|
||||
lv_display_add_event_cb(disp, buf_changed_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
|
||||
lv_display_add_event_cb(disp, delete_event_cb, LV_EVENT_DELETE, NULL);
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void buf_changed_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_display_t * disp = lv_event_get_target(e);
|
||||
lv_color_format_t cf = lv_display_get_color_format(disp);
|
||||
int32_t hor_res = lv_display_get_original_horizontal_resolution(disp);
|
||||
int32_t ver_res = lv_display_get_original_vertical_resolution(disp);
|
||||
|
||||
free(_state.draw_buf.unaligned_data);
|
||||
|
||||
size_t buf_size = 4 * (hor_res + LV_DRAW_BUF_STRIDE_ALIGN - 1) * ver_res + LV_DRAW_BUF_ALIGN;
|
||||
uint8_t * buf = malloc(buf_size);
|
||||
LV_ASSERT_MALLOC(buf);
|
||||
|
||||
lv_draw_buf_init(&_state.draw_buf, hor_res, ver_res, cf, LV_STRIDE_AUTO, lv_draw_buf_align(buf, cf), buf_size);
|
||||
_state.draw_buf.unaligned_data = buf;
|
||||
lv_display_set_draw_buffers(disp, &_state.draw_buf, NULL);
|
||||
}
|
||||
|
||||
static void delete_event_cb(lv_event_t * e)
|
||||
{
|
||||
LV_UNUSED(e);
|
||||
lv_display_t * disp = lv_event_get_target(e);
|
||||
lv_draw_buf_t * draw_buf = lv_display_get_buf_active(disp);
|
||||
free(draw_buf->unaligned_data);
|
||||
|
||||
}
|
||||
|
||||
static void dummy_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p)
|
||||
{
|
||||
LV_UNUSED(area);
|
||||
LV_UNUSED(color_p);
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
55
inc/lvgl/src/debugging/test/lv_test_display.h
Normal file
55
inc/lvgl/src/debugging/test/lv_test_display.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file lv_test_display.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TEST_DISPLAY_H
|
||||
#define LV_TEST_DISPLAY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/***
|
||||
* Create a dummy display for for the tests
|
||||
* @param hor_res the maximal horizontal resolution
|
||||
* @param ver_res the maximal vertical resolution
|
||||
* @return the created display
|
||||
*
|
||||
* @note The resolution can be changed to any smaller values later
|
||||
* using `lv_display_set_resolution`
|
||||
* The color format can be freely changed later using `lv_display_set_color_format`
|
||||
*/
|
||||
lv_display_t * lv_test_display_create(int32_t hor_res, int32_t ver_res);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEST_DISPLAY_H*/
|
||||
193
inc/lvgl/src/debugging/test/lv_test_fs.c
Normal file
193
inc/lvgl/src/debugging/test/lv_test_fs.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* @file lv_test_fs.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_test_fs.h"
|
||||
|
||||
#if LV_USE_TEST
|
||||
|
||||
#include "../../misc/lv_assert.h"
|
||||
#include "../../misc/lv_fs.h"
|
||||
#include "../../stdlib/lv_mem.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_TEST_FS_LETTER 'T'
|
||||
#define LV_TEST_FS_CACHE_SIZE (512)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
|
||||
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p);
|
||||
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
|
||||
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
|
||||
static void * fs_dir_open(lv_fs_drv_t * drv, const char * path);
|
||||
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn, uint32_t fn_len);
|
||||
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * rddir_p);
|
||||
static bool fs_ready(lv_fs_drv_t * drv);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static bool is_ready = true;
|
||||
static lv_fs_drv_t fs_drv;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_test_fs_init(void)
|
||||
{
|
||||
lv_fs_drv_init(&fs_drv);
|
||||
|
||||
/*Set up fields...*/
|
||||
fs_drv.letter = LV_TEST_FS_LETTER;
|
||||
fs_drv.cache_size = LV_TEST_FS_CACHE_SIZE;
|
||||
|
||||
fs_drv.open_cb = fs_open;
|
||||
fs_drv.close_cb = fs_close;
|
||||
fs_drv.read_cb = fs_read;
|
||||
fs_drv.write_cb = fs_write;
|
||||
fs_drv.seek_cb = fs_seek;
|
||||
fs_drv.tell_cb = fs_tell;
|
||||
|
||||
fs_drv.dir_close_cb = fs_dir_close;
|
||||
fs_drv.dir_open_cb = fs_dir_open;
|
||||
fs_drv.dir_read_cb = fs_dir_read;
|
||||
|
||||
fs_drv.ready_cb = fs_ready;
|
||||
|
||||
lv_fs_drv_register(&fs_drv);
|
||||
}
|
||||
|
||||
void lv_test_fs_set_ready(bool ready)
|
||||
{
|
||||
is_ready = ready;
|
||||
}
|
||||
|
||||
void lv_test_fs_clear_open_cb(bool is_clear)
|
||||
{
|
||||
fs_drv.open_cb = is_clear ? NULL : fs_open;
|
||||
}
|
||||
|
||||
void lv_test_fs_clear_close_cb(bool is_clear)
|
||||
{
|
||||
fs_drv.close_cb = is_clear ? NULL : fs_close;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
lv_fs_file_t * file_p = lv_malloc(sizeof(lv_fs_file_t));
|
||||
LV_ASSERT_MALLOC(file_p);
|
||||
if(file_p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_fs_res_t res = lv_fs_open(file_p, path, mode);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
lv_free(file_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return file_p;
|
||||
}
|
||||
|
||||
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
lv_fs_res_t res = lv_fs_close(file_p);
|
||||
lv_free(file_p);
|
||||
return res;
|
||||
}
|
||||
|
||||
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
return lv_fs_read(file_p, buf, btr, br);
|
||||
}
|
||||
|
||||
static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
return lv_fs_write(file_p, buf, btw, bw);
|
||||
}
|
||||
|
||||
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
return lv_fs_seek(file_p, pos, whence);
|
||||
}
|
||||
|
||||
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
return lv_fs_tell(file_p, pos_p);
|
||||
}
|
||||
|
||||
static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
lv_fs_dir_t * rddir_p = lv_malloc(sizeof(lv_fs_dir_t));
|
||||
if(rddir_p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_fs_res_t res = lv_fs_dir_open(rddir_p, path);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
lv_free(rddir_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rddir_p;
|
||||
}
|
||||
|
||||
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * rddir_p, char * fn, uint32_t fn_len)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
return lv_fs_dir_read(rddir_p, fn, fn_len);
|
||||
}
|
||||
|
||||
static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * rddir_p)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
lv_fs_res_t res = lv_fs_dir_close(rddir_p);
|
||||
lv_free(rddir_p);
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool fs_ready(lv_fs_drv_t * drv)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
return is_ready;
|
||||
}
|
||||
|
||||
#endif/*LV_USE_TEST*/
|
||||
69
inc/lvgl/src/debugging/test/lv_test_fs.h
Normal file
69
inc/lvgl/src/debugging/test/lv_test_fs.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @file lv_test_fs.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TEST_FS_H
|
||||
#define LV_TEST_FS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the test file system driver
|
||||
*/
|
||||
void lv_test_fs_init(void);
|
||||
|
||||
/**
|
||||
* Set whether the test file system is ready
|
||||
* @param ready true: ready, false: not ready
|
||||
*/
|
||||
void lv_test_fs_set_ready(bool ready);
|
||||
|
||||
/**
|
||||
* Set whether the open callback of the test file system is cleared
|
||||
* @param is_clear true: clear, false: not clear
|
||||
*/
|
||||
void lv_test_fs_clear_open_cb(bool is_clear);
|
||||
|
||||
/**
|
||||
* Set whether the close callback of the test file system is cleared
|
||||
* @param is_clear true: clear, false: not clear
|
||||
*/
|
||||
void lv_test_fs_clear_close_cb(bool is_clear);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEST_FS_H*/
|
||||
|
||||
|
||||
60
inc/lvgl/src/debugging/test/lv_test_helpers.c
Normal file
60
inc/lvgl/src/debugging/test/lv_test_helpers.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file lv_test_helpers.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_test_helpers.h"
|
||||
|
||||
#if LV_USE_TEST
|
||||
#include "../../lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_test_wait(uint32_t ms)
|
||||
{
|
||||
while(ms) {
|
||||
lv_tick_inc(1);
|
||||
lv_timer_handler();
|
||||
ms--;
|
||||
}
|
||||
lv_refr_now(NULL);
|
||||
}
|
||||
|
||||
void lv_test_fast_forward(uint32_t ms)
|
||||
{
|
||||
lv_tick_inc(ms);
|
||||
lv_timer_handler();
|
||||
lv_refr_now(NULL);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
80
inc/lvgl/src/debugging/test/lv_test_helpers.h
Normal file
80
inc/lvgl/src/debugging/test/lv_test_helpers.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @file lv_test_helpers.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TEST_HELPERS_H
|
||||
#define LV_TEST_HELPERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
#include "../../stdlib/lv_mem.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Emulate a delay. It's not real delay, but it tricks LVGL to think that the
|
||||
* required time has been elapsed.
|
||||
* `lv_timer_handler` is called after each millisecond, meaning all the events
|
||||
* will be fired inside this function.
|
||||
* At the end the animations and display will be also updated.
|
||||
* @param ms the number of milliseconds to pass
|
||||
*/
|
||||
void lv_test_wait(uint32_t ms);
|
||||
|
||||
/**
|
||||
* Emulates some time passing.
|
||||
* Update the animations and the display only once at the end.
|
||||
* @param ms the number of milliseconds to pass
|
||||
*/
|
||||
void lv_test_fast_forward(uint32_t ms);
|
||||
|
||||
#if LV_USE_STDLIB_MALLOC != LV_STDLIB_BUILTIN
|
||||
/* Skip checking heap as we don't have the info available */
|
||||
#define LV_HEAP_CHECK(x) do {} while(0)
|
||||
/* Pick a non-zero value */
|
||||
#define lv_test_get_free_mem() (65536)
|
||||
#else
|
||||
#define LV_HEAP_CHECK(x) x
|
||||
|
||||
static inline size_t lv_test_get_free_mem(void)
|
||||
{
|
||||
lv_mem_monitor_t m1;
|
||||
lv_mem_monitor(&m1);
|
||||
return m1.free_size;
|
||||
}
|
||||
#endif /* LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN */
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define LV_TEST_WIDTH_TO_STRIDE(w, px_size) ((((w) * (px_size) + (LV_DRAW_BUF_STRIDE_ALIGN - 1)) / LV_DRAW_BUF_STRIDE_ALIGN) * LV_DRAW_BUF_STRIDE_ALIGN)
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEST_HELPERS_H*/
|
||||
212
inc/lvgl/src/debugging/test/lv_test_indev.c
Normal file
212
inc/lvgl/src/debugging/test/lv_test_indev.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* @file lv_test_indev.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_test.h"
|
||||
#if LV_USE_TEST
|
||||
|
||||
#include "../../core/lv_global.h"
|
||||
#include "../../lvgl_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_test_mouse_read_cb(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
static void lv_test_keypad_read_cb(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
static void lv_test_encoder_read_cb(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#define _state LV_GLOBAL_DEFAULT()->test_state
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_test_indev_create_all(void)
|
||||
{
|
||||
_state.mouse_indev = lv_indev_create();
|
||||
lv_indev_set_type(_state.mouse_indev, LV_INDEV_TYPE_POINTER);
|
||||
lv_indev_set_read_cb(_state.mouse_indev, lv_test_mouse_read_cb);
|
||||
|
||||
_state.keypad_indev = lv_indev_create();
|
||||
lv_indev_set_type(_state.keypad_indev, LV_INDEV_TYPE_KEYPAD);
|
||||
lv_indev_set_read_cb(_state.keypad_indev, lv_test_keypad_read_cb);
|
||||
|
||||
_state.encoder_indev = lv_indev_create();
|
||||
lv_indev_set_type(_state.encoder_indev, LV_INDEV_TYPE_ENCODER);
|
||||
lv_indev_set_read_cb(_state.encoder_indev, lv_test_encoder_read_cb);
|
||||
}
|
||||
|
||||
void lv_test_indev_delete_all(void)
|
||||
{
|
||||
if(_state.mouse_indev) {
|
||||
lv_indev_delete(_state.mouse_indev);
|
||||
_state.mouse_indev = NULL;
|
||||
}
|
||||
|
||||
if(_state.keypad_indev) {
|
||||
lv_indev_delete(_state.keypad_indev);
|
||||
_state.keypad_indev = NULL;
|
||||
}
|
||||
|
||||
if(_state.encoder_indev) {
|
||||
lv_indev_delete(_state.encoder_indev);
|
||||
_state.encoder_indev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lv_indev_t * lv_test_indev_get_indev(lv_indev_type_t type)
|
||||
{
|
||||
switch(type) {
|
||||
case LV_INDEV_TYPE_POINTER:
|
||||
return _state.mouse_indev;
|
||||
case LV_INDEV_TYPE_KEYPAD:
|
||||
return _state.keypad_indev;
|
||||
case LV_INDEV_TYPE_ENCODER:
|
||||
return _state.encoder_indev;
|
||||
default:
|
||||
return NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void lv_test_mouse_move_to(int32_t x, int32_t y)
|
||||
{
|
||||
_state.x_act = x;
|
||||
_state.y_act = y;
|
||||
}
|
||||
|
||||
|
||||
void lv_test_mouse_move_to_obj(lv_obj_t * obj)
|
||||
{
|
||||
int32_t x = obj->coords.x1 + lv_obj_get_width(obj) / 2;
|
||||
int32_t y = obj->coords.y1 + lv_obj_get_height(obj) / 2;
|
||||
lv_test_mouse_move_to(x, y);
|
||||
}
|
||||
|
||||
void lv_test_mouse_move_by(int32_t x, int32_t y)
|
||||
{
|
||||
_state.x_act += x;
|
||||
_state.y_act += y;
|
||||
}
|
||||
|
||||
void lv_test_mouse_press(void)
|
||||
{
|
||||
_state.mouse_pressed = true;
|
||||
}
|
||||
|
||||
void lv_test_mouse_release(void)
|
||||
{
|
||||
_state.mouse_pressed = false;
|
||||
}
|
||||
|
||||
void lv_test_mouse_click_at(int32_t x, int32_t y)
|
||||
{
|
||||
lv_test_mouse_release();
|
||||
lv_test_wait(50);
|
||||
lv_test_mouse_move_to(x, y);
|
||||
lv_test_mouse_press();
|
||||
lv_test_wait(50);
|
||||
lv_test_mouse_release();
|
||||
lv_test_wait(50);
|
||||
}
|
||||
|
||||
void lv_test_key_press(uint32_t k)
|
||||
{
|
||||
_state.key_act = k;
|
||||
_state.key_pressed = true;
|
||||
}
|
||||
|
||||
void lv_test_key_release(void)
|
||||
{
|
||||
_state.key_pressed = false;
|
||||
}
|
||||
|
||||
void lv_test_key_hit(uint32_t k)
|
||||
{
|
||||
lv_test_key_release();
|
||||
lv_test_wait(50);
|
||||
lv_test_key_press(k);
|
||||
lv_test_wait(50);
|
||||
lv_test_key_release();
|
||||
lv_test_wait(50);
|
||||
}
|
||||
|
||||
void lv_test_encoder_add_diff(int32_t d)
|
||||
{
|
||||
_state.diff_act += d;
|
||||
}
|
||||
|
||||
void lv_test_encoder_turn(int32_t d)
|
||||
{
|
||||
_state.diff_act += d;
|
||||
lv_test_wait(50);
|
||||
}
|
||||
|
||||
void lv_test_encoder_press(void)
|
||||
{
|
||||
_state.enc_pressed = true;
|
||||
}
|
||||
|
||||
void lv_test_encoder_release(void)
|
||||
{
|
||||
_state.enc_pressed = false;
|
||||
}
|
||||
|
||||
void lv_test_encoder_click(void)
|
||||
{
|
||||
lv_test_encoder_release();
|
||||
lv_test_wait(50);
|
||||
lv_test_encoder_press();
|
||||
lv_test_wait(50);
|
||||
lv_test_encoder_release();
|
||||
lv_test_wait(50);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_test_mouse_read_cb(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
LV_UNUSED(indev);
|
||||
lv_point_set(&data->point, _state.x_act, _state.y_act);
|
||||
data->state = _state.mouse_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
|
||||
|
||||
static void lv_test_keypad_read_cb(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
LV_UNUSED(indev);
|
||||
data->key = _state.key_act;
|
||||
data->state = _state.key_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
|
||||
|
||||
static void lv_test_encoder_read_cb(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
LV_UNUSED(indev);
|
||||
data->enc_diff = _state.diff_act;
|
||||
data->state = _state.enc_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
|
||||
_state.diff_act = 0;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
171
inc/lvgl/src/debugging/test/lv_test_indev.h
Normal file
171
inc/lvgl/src/debugging/test/lv_test_indev.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* @file lv_test_indev.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TEST_INDEV_H
|
||||
#define LV_TEST_INDEV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
#include "../../indev/lv_indev.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a mouse (pointer), keypad, and encoder indevs.
|
||||
* They can be controlled via function calls during the test
|
||||
*/
|
||||
void lv_test_indev_create_all(void);
|
||||
|
||||
/**
|
||||
* Delete all test input devices
|
||||
*/
|
||||
void lv_test_indev_delete_all(void);
|
||||
|
||||
/**
|
||||
* Get one of the indev created in `lv_test_indev_create_all`
|
||||
* @param type type of the indev to get
|
||||
* @return the indev
|
||||
*/
|
||||
lv_indev_t * lv_test_indev_get_indev(lv_indev_type_t type);
|
||||
|
||||
/**
|
||||
* Move the mouse to the given coordinates.
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
* @param x the target absolute X coordinate
|
||||
* @param y the target absolute Y coordinate
|
||||
*/
|
||||
void lv_test_mouse_move_to(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Move the mouse to the center of a widget
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
* @param obj pointer to an widget
|
||||
*/
|
||||
void lv_test_mouse_move_to_obj(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Move the mouse cursor. Keep the pressed or released state
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
* @param x the difference in X to move
|
||||
* @param y the difference in Y to move
|
||||
*/
|
||||
void lv_test_mouse_move_by(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Make the mouse button pressed.
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
*/
|
||||
void lv_test_mouse_press(void);
|
||||
|
||||
/**
|
||||
* Make the mouse button released.
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
*/
|
||||
void lv_test_mouse_release(void);
|
||||
|
||||
/**
|
||||
* Emulate a click on a given point.
|
||||
* First set the released state, wait a little, press, wait, and release again.
|
||||
* The wait time is 50ms.
|
||||
* Internally `lv_timer_handler` is called, meaning all the events will be fired inside this function.
|
||||
* @param x the target absolute X coordinate
|
||||
* @param y the target absolute Y coordinate
|
||||
*/
|
||||
void lv_test_mouse_click_at(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Emulate a key press.
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
* @param k the key to press
|
||||
*/
|
||||
void lv_test_key_press(uint32_t k);
|
||||
|
||||
/**
|
||||
* Release the previously press key.
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
* @param k the key to press
|
||||
*/
|
||||
void lv_test_key_release(void);
|
||||
|
||||
/**
|
||||
* Emulate a key hit.
|
||||
* First set the released state, wait a little, press, wait, and release again.
|
||||
* The wait time is 50ms.
|
||||
* Internally `lv_timer_handler` is called, meaning all the events will be fired inside this function.
|
||||
* @param k the key to hit
|
||||
*/
|
||||
void lv_test_key_hit(uint32_t k);
|
||||
|
||||
|
||||
/**
|
||||
* Emulate encoder rotation, use positive parameter to rotate to the right
|
||||
* and negative to rotate to the left.
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
* @param d number of encoder ticks to emulate
|
||||
*/
|
||||
void lv_test_encoder_add_diff(int32_t d);
|
||||
|
||||
/**
|
||||
* Emulate an encoder turn a wait 50ms. Use positive parameter to rotate to the right
|
||||
* and negative to rotate to the left.
|
||||
* Internally `lv_timer_handler` is called, meaning all the events will be fired inside this function.
|
||||
* @param d number of encoder ticks to emulate
|
||||
*/
|
||||
void lv_test_encoder_turn(int32_t d);
|
||||
|
||||
/**
|
||||
* Emulate an encoder press.
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
*/
|
||||
void lv_test_encoder_press(void);
|
||||
|
||||
/**
|
||||
* Emulate an encoder release.
|
||||
* This function doesn't wait, but just changes the state and returns immediately.
|
||||
*/
|
||||
void lv_test_encoder_release(void);
|
||||
|
||||
/**
|
||||
* Emulate am encoder click.
|
||||
* First set the released state, wait a little, press, wait, and release again.
|
||||
* The wait time is 50ms.
|
||||
* Internally `lv_timer_handler` is called, meaning all the events will be fired inside this function.
|
||||
*/
|
||||
void lv_test_encoder_click(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEST_INDEV_H*/
|
||||
|
||||
|
||||
|
||||
|
||||
141
inc/lvgl/src/debugging/test/lv_test_indev_gesture.c
Normal file
141
inc/lvgl/src/debugging/test/lv_test_indev_gesture.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* @file lv_test_indev_gesture.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_test.h"
|
||||
#if LV_USE_TEST && LV_USE_GESTURE_RECOGNITION
|
||||
|
||||
#include "../../core/lv_global.h"
|
||||
#include "../../lvgl_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define MAX_TOUCH_CNT 2
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_test_gesture_read_cb(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#define _state LV_GLOBAL_DEFAULT()->test_state
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_test_indev_gesture_create(void)
|
||||
{
|
||||
_state.max_touch_cnt = MAX_TOUCH_CNT;
|
||||
_state.touch_data =
|
||||
lv_malloc_zeroed(sizeof(lv_indev_touch_data_t) * _state.max_touch_cnt);
|
||||
if(_state.touch_data == NULL) {
|
||||
LV_LOG_ERROR("lv_indev_touch_data_t malloc failed");
|
||||
}
|
||||
|
||||
_state.gesture_indev = lv_indev_create();
|
||||
lv_indev_set_type(_state.gesture_indev, LV_INDEV_TYPE_POINTER);
|
||||
lv_indev_set_read_cb(_state.gesture_indev, lv_test_gesture_read_cb);
|
||||
}
|
||||
|
||||
void lv_test_indev_gesture_delete(void)
|
||||
{
|
||||
if(_state.gesture_indev) {
|
||||
lv_indev_delete(_state.gesture_indev);
|
||||
_state.gesture_indev = NULL;
|
||||
}
|
||||
|
||||
if(_state.touch_data) {
|
||||
lv_free(_state.touch_data);
|
||||
_state.touch_data = NULL;
|
||||
}
|
||||
|
||||
_state.max_touch_cnt = 0;
|
||||
}
|
||||
|
||||
lv_indev_t * lv_test_indev_get_gesture_indev(lv_indev_type_t type)
|
||||
{
|
||||
switch(type) {
|
||||
case LV_INDEV_TYPE_POINTER:
|
||||
return _state.gesture_indev;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_test_gesture_set_pinch_data(lv_point_t point_0, lv_point_t point_1)
|
||||
{
|
||||
_state.touch_data[0].id = 0;
|
||||
_state.touch_data[0].point = point_0;
|
||||
_state.touch_data[1].id = 1;
|
||||
_state.touch_data[1].point = point_1;
|
||||
}
|
||||
|
||||
void lv_test_gesture_pinch_press(void)
|
||||
{
|
||||
_state.touch_data[0].state = LV_INDEV_STATE_PRESSED;
|
||||
_state.touch_data[1].state = LV_INDEV_STATE_PRESSED;
|
||||
}
|
||||
|
||||
void lv_test_gesture_pinch_release(void)
|
||||
{
|
||||
_state.touch_data[0].state = LV_INDEV_STATE_RELEASED;
|
||||
_state.touch_data[1].state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
|
||||
void lv_test_gesture_pinch(lv_point_t point_begin_0, lv_point_t point_begin_1,
|
||||
lv_point_t point_end_0, lv_point_t point_end_1)
|
||||
{
|
||||
lv_test_gesture_pinch_release();
|
||||
lv_test_wait(50);
|
||||
lv_test_gesture_set_pinch_data(point_begin_0, point_begin_1);
|
||||
lv_test_gesture_pinch_press();
|
||||
lv_test_wait(50);
|
||||
lv_test_gesture_set_pinch_data(point_end_0, point_end_1);
|
||||
lv_test_wait(80);
|
||||
lv_test_gesture_set_pinch_data(point_end_0, point_end_1);
|
||||
lv_test_wait(80);
|
||||
lv_test_gesture_pinch_release();
|
||||
lv_test_wait(50);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_test_gesture_read_cb(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
LV_UNUSED(indev);
|
||||
|
||||
lv_indev_gesture_recognizers_update(indev,
|
||||
_state.touch_data,
|
||||
_state.max_touch_cnt);
|
||||
lv_indev_gesture_recognizers_set_data(indev, data);
|
||||
if(_state.touch_data != NULL && _state.max_touch_cnt > 0) {
|
||||
data->point.x = _state.touch_data[0].point.x;
|
||||
data->point.y = _state.touch_data[0].point.y;
|
||||
}
|
||||
else {
|
||||
LV_LOG_ERROR("Invalid touch data or max touch count");
|
||||
data->point.x = 0;
|
||||
data->point.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
93
inc/lvgl/src/debugging/test/lv_test_indev_gesture.h
Normal file
93
inc/lvgl/src/debugging/test/lv_test_indev_gesture.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file lv_test_indev_gesture.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TEST_INDEV_GESTURE_H
|
||||
#define LV_TEST_INDEV_GESTURE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST && LV_USE_GESTURE_RECOGNITION
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
#include "../../indev/lv_indev.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a touch (pointer) indevs.
|
||||
* They can be controlled via function calls during the test
|
||||
*/
|
||||
void lv_test_indev_gesture_create(void);
|
||||
|
||||
/**
|
||||
* Delete the touch (pointer) indevs.
|
||||
*/
|
||||
void lv_test_indev_gesture_delete(void);
|
||||
|
||||
/**
|
||||
* Get one of the indev created in `lv_test_indev_gesture_create`
|
||||
* @param type type of the indev to get
|
||||
* @return the indev
|
||||
*/
|
||||
lv_indev_t * lv_test_indev_get_gesture_indev(lv_indev_type_t type);
|
||||
|
||||
/**
|
||||
* Set two touch points data for pinch gesture
|
||||
* @param point_0 First touch point coordinates
|
||||
* @param point_1 Second touch point coordinates
|
||||
*/
|
||||
void lv_test_gesture_set_pinch_data(lv_point_t point_0, lv_point_t point_1);
|
||||
|
||||
/**
|
||||
* Trigger press state of pinch gesture (both touch points pressed)
|
||||
*/
|
||||
void lv_test_gesture_pinch_press(void);
|
||||
|
||||
/**
|
||||
* Trigger release state of pinch gesture (both touch points released)
|
||||
*/
|
||||
void lv_test_gesture_pinch_release(void);
|
||||
|
||||
/**
|
||||
* Simulate a complete pinch gesture operation
|
||||
* @param point_begin_0 Starting coordinates of first touch point
|
||||
* @param point_begin_1 Starting coordinates of second touch point
|
||||
* @param point_end_0 Ending coordinates of first touch point
|
||||
* @param point_end_1 Ending coordinates of second touch point
|
||||
*/
|
||||
void lv_test_gesture_pinch(lv_point_t point_begin_0, lv_point_t point_begin_1,
|
||||
lv_point_t point_end_0, lv_point_t point_end_1);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_TEST && LV_USE_GESTURE_RECOGNITION*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEST_INDEV_GESTURE_H*/
|
||||
|
||||
|
||||
|
||||
|
||||
67
inc/lvgl/src/debugging/test/lv_test_private.h
Normal file
67
inc/lvgl/src/debugging/test/lv_test_private.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file lv_test_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TEST_PRIVATE_H
|
||||
#define LV_TEST_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
#include "../../indev/lv_indev_gesture.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_indev_t * mouse_indev;
|
||||
lv_indev_t * keypad_indev;
|
||||
lv_indev_t * encoder_indev;
|
||||
|
||||
lv_draw_buf_t draw_buf;
|
||||
|
||||
int32_t x_act;
|
||||
int32_t y_act;
|
||||
uint32_t key_act;
|
||||
int32_t diff_act;
|
||||
bool mouse_pressed;
|
||||
bool key_pressed;
|
||||
bool enc_pressed;
|
||||
|
||||
#if LV_USE_GESTURE_RECOGNITION
|
||||
lv_indev_t * gesture_indev;
|
||||
lv_indev_touch_data_t * touch_data;
|
||||
uint8_t max_touch_cnt;
|
||||
#endif
|
||||
} lv_test_state_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_TEST*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*LV_TEST_PRIVATE_H*/
|
||||
348
inc/lvgl/src/debugging/test/lv_test_screenshot_compare.c
Normal file
348
inc/lvgl/src/debugging/test/lv_test_screenshot_compare.c
Normal file
@@ -0,0 +1,348 @@
|
||||
/**
|
||||
* @file lv_test_screenshot_compare.c
|
||||
*
|
||||
* Copyright 2002-2010 Guillaume Cottenceau.
|
||||
*
|
||||
* This software may be freely redistributed under the terms
|
||||
* of the X11 license.
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST && defined(LV_USE_TEST_SCREENSHOT_COMPARE) && LV_USE_TEST_SCREENSHOT_COMPARE
|
||||
|
||||
#if LV_USE_LODEPNG == 0
|
||||
#error "lodepng is required for screenshot compare. Enable it in lv_conf.h (LV_USE_LODEPNG 1)"
|
||||
#endif
|
||||
|
||||
#include "../../lvgl.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include "../../libs/lodepng/lodepng.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#define mkdir(pathname, mode) _mkdir(pathname)
|
||||
#define strtok_r strtok_s
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#ifndef REF_IMGS_PATH
|
||||
#define REF_IMGS_PATH ""
|
||||
#endif
|
||||
|
||||
#ifndef REF_IMG_TOLERANCE
|
||||
#define REF_IMG_TOLERANCE 0
|
||||
#endif
|
||||
|
||||
#define ERR_FILE_NOT_FOUND -1
|
||||
#define ERR_PNG -2
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_test_screenshot_result_t screenshot_compare(const char * fn_ref, uint8_t tolerance);
|
||||
static unsigned read_png_file(lv_draw_buf_t ** refr_draw_buf, unsigned * width, unsigned * height,
|
||||
const char * file_name);
|
||||
static unsigned write_png_file(void * raw_img, uint32_t width, uint32_t height, char * file_name);
|
||||
static void buf_to_xrgb8888(const lv_draw_buf_t * draw_buf, uint8_t * buf_out);
|
||||
static void create_folders_if_needed(const char * path) ;
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_test_screenshot_result_t lv_test_screenshot_compare(const char * fn_ref)
|
||||
{
|
||||
|
||||
lv_obj_t * scr = lv_screen_active();
|
||||
lv_obj_invalidate(scr);
|
||||
lv_refr_now(NULL);
|
||||
|
||||
lv_test_screenshot_result_t res;
|
||||
res = screenshot_compare(fn_ref, REF_IMG_TOLERANCE);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Compare the content of the frame buffer with a reference image
|
||||
* @param fn_ref reference image path
|
||||
* @return An element of lv_test_screenshot_result_t
|
||||
*/
|
||||
static lv_test_screenshot_result_t screenshot_compare(const char * fn_ref, uint8_t tolerance)
|
||||
{
|
||||
char fn_ref_full[256];
|
||||
lv_snprintf(fn_ref_full, sizeof(fn_ref_full), "%s%s", REF_IMGS_PATH, fn_ref);
|
||||
|
||||
#if LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE
|
||||
create_folders_if_needed(fn_ref_full);
|
||||
#endif
|
||||
|
||||
lv_draw_buf_t * draw_buf = lv_display_get_buf_active(NULL);
|
||||
|
||||
uint8_t * screen_buf_xrgb8888 = lv_malloc(draw_buf->header.w * draw_buf->header.h * 4);
|
||||
if(!screen_buf_xrgb8888) {
|
||||
LV_LOG_ERROR("Not enough memory to compare display with screenshot");
|
||||
return LV_TEST_SCREENSHOT_RESULT_FAILED;
|
||||
}
|
||||
|
||||
buf_to_xrgb8888(draw_buf, screen_buf_xrgb8888);
|
||||
|
||||
lv_draw_buf_t * ref_draw_buf = NULL;
|
||||
unsigned ref_img_width = 0;
|
||||
unsigned ref_img_height = 0;
|
||||
unsigned res = read_png_file(&ref_draw_buf, &ref_img_width, &ref_img_height, fn_ref_full);
|
||||
if(res) {
|
||||
lv_test_screenshot_result_t comp_res;
|
||||
#if LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE
|
||||
LV_LOG_WARN("%s%s", fn_ref_full, " was not found, creating it now from the rendered screen");
|
||||
write_png_file(screen_buf_xrgb8888, draw_buf->header.w, draw_buf->header.h, fn_ref_full);
|
||||
comp_res = LV_TEST_SCREENSHOT_RESULT_PASSED;
|
||||
#else
|
||||
comp_res = LV_TEST_SCREENSHOT_RESULT_NO_REFERENCE_IMAGE;
|
||||
#endif
|
||||
lv_free(screen_buf_xrgb8888);
|
||||
if(ref_draw_buf) lv_draw_buf_destroy(ref_draw_buf);
|
||||
return comp_res;
|
||||
}
|
||||
|
||||
if(ref_img_width != draw_buf->header.w || ref_img_height != draw_buf->header.h) {
|
||||
LV_LOG_WARN("The dimensions of the rendered and the %s reference image don't match", fn_ref);
|
||||
lv_free(screen_buf_xrgb8888);
|
||||
if(ref_draw_buf) lv_draw_buf_destroy(ref_draw_buf);
|
||||
return LV_TEST_SCREENSHOT_RESULT_FAILED;
|
||||
}
|
||||
|
||||
|
||||
unsigned x, y;
|
||||
bool err = false;
|
||||
for(y = 0; y < ref_img_height; y++) {
|
||||
uint8_t * screen_buf_tmp = screen_buf_xrgb8888 + draw_buf->header.w * 4 * y;
|
||||
uint8_t * ref_row = (uint8_t *)ref_draw_buf->data + y * ref_draw_buf->header.stride;
|
||||
for(x = 0; x < ref_img_width; x++) {
|
||||
uint8_t * ptr_ref = &(ref_row[x * 4]);
|
||||
uint8_t * ptr_act = &screen_buf_tmp[x * 4];
|
||||
|
||||
if(LV_ABS((int32_t) ptr_act[0] - (int32_t) ptr_ref[0]) > tolerance ||
|
||||
LV_ABS((int32_t) ptr_act[1] - (int32_t) ptr_ref[1]) > tolerance ||
|
||||
LV_ABS((int32_t) ptr_act[2] - (int32_t) ptr_ref[2]) > tolerance) {
|
||||
uint32_t act_px = (ptr_act[2] << 16) + (ptr_act[1] << 8) + (ptr_act[0] << 0);
|
||||
uint32_t ref_px = 0;
|
||||
memcpy(&ref_px, ptr_ref, 3);
|
||||
LV_LOG("\nScreenshot compare error\n"
|
||||
" - File: %s\n"
|
||||
" - At x:%d, y:%d.\n"
|
||||
" - Expected: %X\n"
|
||||
" - Actual: %X\n"
|
||||
" - Tolerance: %d\n",
|
||||
fn_ref_full, x, y, ref_px, act_px, tolerance);
|
||||
err = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(err) break;
|
||||
}
|
||||
|
||||
if(err) {
|
||||
char fn_ref_no_ext[128];
|
||||
lv_strlcpy(fn_ref_no_ext, fn_ref, sizeof(fn_ref_no_ext));
|
||||
fn_ref_no_ext[strlen(fn_ref_no_ext) - 4] = '\0';
|
||||
|
||||
char fn_err_full[256];
|
||||
lv_snprintf(fn_err_full, sizeof(fn_err_full), "%s%s_err.png", REF_IMGS_PATH, fn_ref_no_ext);
|
||||
|
||||
write_png_file(screen_buf_xrgb8888, draw_buf->header.w, draw_buf->header.h, fn_err_full);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
lv_free(screen_buf_xrgb8888);
|
||||
if(ref_draw_buf) lv_draw_buf_destroy(ref_draw_buf);
|
||||
return err ? LV_TEST_SCREENSHOT_RESULT_FAILED : LV_TEST_SCREENSHOT_RESULT_PASSED;
|
||||
|
||||
}
|
||||
|
||||
static unsigned read_png_file(lv_draw_buf_t ** refr_draw_buf, unsigned * width, unsigned * height,
|
||||
const char * file_name)
|
||||
{
|
||||
unsigned error = lodepng_decode32_file((void *)refr_draw_buf, width, height, file_name);
|
||||
if(error) LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
static unsigned write_png_file(void * raw_img, uint32_t width, uint32_t height, char * file_name)
|
||||
{
|
||||
unsigned error = lodepng_encode32_file(file_name, raw_img, width, height);
|
||||
if(error) LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
static void buf_to_xrgb8888(const lv_draw_buf_t * draw_buf, uint8_t * buf_out)
|
||||
{
|
||||
uint32_t stride = draw_buf->header.stride;
|
||||
lv_color_format_t cf_in = draw_buf->header.cf;
|
||||
const uint8_t * buf_in = draw_buf->data;
|
||||
|
||||
if(cf_in == LV_COLOR_FORMAT_RGB565 || cf_in == LV_COLOR_FORMAT_RGB565_SWAPPED) {
|
||||
if(cf_in == LV_COLOR_FORMAT_RGB565_SWAPPED) {
|
||||
lv_draw_sw_rgb565_swap(draw_buf->data, draw_buf->header.w * draw_buf->header.h);
|
||||
}
|
||||
uint32_t y;
|
||||
for(y = 0; y < draw_buf->header.h; y++) {
|
||||
|
||||
uint32_t x;
|
||||
for(x = 0; x < draw_buf->header.w; x++) {
|
||||
const lv_color16_t * c16 = (const lv_color16_t *)&buf_in[x * 2];
|
||||
|
||||
buf_out[x * 4 + 3] = 0xff;
|
||||
buf_out[x * 4 + 2] = (c16->blue * 2106) >> 8; /*To make it rounded*/
|
||||
buf_out[x * 4 + 1] = (c16->green * 1037) >> 8;
|
||||
buf_out[x * 4 + 0] = (c16->red * 2106) >> 8;
|
||||
}
|
||||
|
||||
buf_in += stride;
|
||||
buf_out += draw_buf->header.w * 4;
|
||||
}
|
||||
}
|
||||
else if(cf_in == LV_COLOR_FORMAT_ARGB8888 || cf_in == LV_COLOR_FORMAT_XRGB8888 ||
|
||||
cf_in == LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED) {
|
||||
uint32_t y;
|
||||
for(y = 0; y < draw_buf->header.h; y++) {
|
||||
uint32_t x;
|
||||
for(x = 0; x < draw_buf->header.w; x++) {
|
||||
buf_out[x * 4 + 3] = buf_in[x * 4 + 3];
|
||||
buf_out[x * 4 + 2] = buf_in[x * 4 + 0];
|
||||
buf_out[x * 4 + 1] = buf_in[x * 4 + 1];
|
||||
buf_out[x * 4 + 0] = buf_in[x * 4 + 2];
|
||||
}
|
||||
|
||||
buf_in += stride;
|
||||
buf_out += draw_buf->header.w * 4;
|
||||
}
|
||||
}
|
||||
else if(cf_in == LV_COLOR_FORMAT_RGB888) {
|
||||
uint32_t y;
|
||||
for(y = 0; y < draw_buf->header.h; y++) {
|
||||
uint32_t x;
|
||||
for(x = 0; x < draw_buf->header.w; x++) {
|
||||
buf_out[x * 4 + 3] = 0xff;
|
||||
buf_out[x * 4 + 2] = buf_in[x * 3 + 0];
|
||||
buf_out[x * 4 + 1] = buf_in[x * 3 + 1];
|
||||
buf_out[x * 4 + 0] = buf_in[x * 3 + 2];
|
||||
}
|
||||
|
||||
buf_in += stride;
|
||||
buf_out += draw_buf->header.w * 4;
|
||||
}
|
||||
}
|
||||
else if(cf_in == LV_COLOR_FORMAT_L8) {
|
||||
uint32_t y;
|
||||
for(y = 0; y < draw_buf->header.h; y++) {
|
||||
uint32_t x;
|
||||
for(x = 0; x < draw_buf->header.w; x++) {
|
||||
buf_out[x * 4 + 3] = 0xff;
|
||||
buf_out[x * 4 + 2] = buf_in[x];
|
||||
buf_out[x * 4 + 1] = buf_in[x];
|
||||
buf_out[x * 4 + 0] = buf_in[x];
|
||||
}
|
||||
|
||||
buf_in += stride;
|
||||
buf_out += draw_buf->header.w * 4;
|
||||
}
|
||||
}
|
||||
else if(cf_in == LV_COLOR_FORMAT_AL88) {
|
||||
uint32_t y;
|
||||
for(y = 0; y < draw_buf->header.h; y++) {
|
||||
uint32_t x;
|
||||
for(x = 0; x < draw_buf->header.w; x++) {
|
||||
buf_out[x * 4 + 3] = buf_in[x * 2 + 1];
|
||||
buf_out[x * 4 + 2] = buf_in[x * 2 + 0];
|
||||
buf_out[x * 4 + 1] = buf_in[x * 2 + 0];
|
||||
buf_out[x * 4 + 0] = buf_in[x * 2 + 0];
|
||||
}
|
||||
|
||||
buf_in += stride;
|
||||
buf_out += draw_buf->header.w * 4;
|
||||
}
|
||||
}
|
||||
else if(cf_in == LV_COLOR_FORMAT_I1) {
|
||||
buf_in += 8;
|
||||
uint32_t y;
|
||||
for(y = 0; y < draw_buf->header.h; y++) {
|
||||
uint32_t x;
|
||||
for(x = 0; x < draw_buf->header.w; x++) {
|
||||
const uint8_t byte = buf_in[x / 8] ;
|
||||
const uint8_t bit_pos = x % 8;
|
||||
const uint8_t pixel = (byte >> (7 - bit_pos)) & 0x01;
|
||||
|
||||
buf_out[x * 4 + 3] = 0xff;
|
||||
buf_out[x * 4 + 2] = pixel ? 0xff : 0x00;
|
||||
buf_out[x * 4 + 1] = pixel ? 0xff : 0x00;
|
||||
buf_out[x * 4 + 0] = pixel ? 0xff : 0x00;
|
||||
}
|
||||
|
||||
buf_in += stride;
|
||||
buf_out += draw_buf->header.w * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void create_folders_if_needed(const char * path)
|
||||
{
|
||||
char * ptr;
|
||||
char * path_copy = lv_strdup(path);
|
||||
if(path_copy == NULL) {
|
||||
LV_LOG_ERROR("Error duplicating path");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char * token = strtok_r(path_copy, "/", &ptr);
|
||||
char current_path[1024] = {'\0'}; /* Adjust the size as needed */
|
||||
|
||||
while(token && ptr && *ptr != '\0') {
|
||||
lv_strcat(current_path, token);
|
||||
lv_strcat(current_path, "/");
|
||||
|
||||
int mkdir_retval = mkdir(current_path, 0777);
|
||||
if(mkdir_retval == 0) {
|
||||
LV_LOG_INFO("Created folder: %s\n", current_path);
|
||||
}
|
||||
else if(errno != EEXIST) {
|
||||
perror("Error creating folder");
|
||||
lv_free(path_copy);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
token = strtok_r(NULL, "/", &ptr);
|
||||
}
|
||||
|
||||
lv_free(path_copy);
|
||||
}
|
||||
|
||||
#endif
|
||||
79
inc/lvgl/src/debugging/test/lv_test_screenshot_compare.h
Normal file
79
inc/lvgl/src/debugging/test/lv_test_screenshot_compare.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file lv_test_screenshot_compare.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_TEST_SCREENSHOT_COMPARE_H
|
||||
#define LV_TEST_SCREENSHOT_COMPARE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../lv_conf_internal.h"
|
||||
#if LV_USE_TEST && defined(LV_USE_TEST_SCREENSHOT_COMPARE) && LV_USE_TEST_SCREENSHOT_COMPARE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return value of `lv_test_screenshot_compare`
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* The screenshot is different than the reference image
|
||||
*/
|
||||
LV_TEST_SCREENSHOT_RESULT_FAILED,
|
||||
|
||||
/**
|
||||
* The screenshot is the same as the reference image.
|
||||
* It is also returned if `LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE` is enabled
|
||||
* and the reference image was missing.
|
||||
*/
|
||||
LV_TEST_SCREENSHOT_RESULT_PASSED,
|
||||
|
||||
/**
|
||||
* If `LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE` is not enabled
|
||||
* and the reference image is missing.
|
||||
*/
|
||||
LV_TEST_SCREENSHOT_RESULT_NO_REFERENCE_IMAGE,
|
||||
|
||||
} lv_test_screenshot_result_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Compare the current content of the test screen with a reference PNG image
|
||||
* - If the reference image is not found it will be created automatically from the rendered screen.
|
||||
* - If the compare fails an `<image_name>_err.png` file will be created with the rendered content next to the reference image.
|
||||
*
|
||||
* It requires lodepng.
|
||||
*
|
||||
* @param fn_ref path to the reference image. Will be appended to REF_IMGS_PATH if set.
|
||||
* @return An element of `lv_test_screenshot_result_t`
|
||||
* @note This function assumes that the default display is the test display that was created by
|
||||
* `lv_test_display_create()`
|
||||
*/
|
||||
lv_test_screenshot_result_t lv_test_screenshot_compare(const char * fn_ref);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_TEST_SCREENSHOT_COMPARE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_TEST_SCREENSHOT_COMPARE_H*/
|
||||
Reference in New Issue
Block a user