multi-disp: API updates
This commit is contained in:
21
README.md
21
README.md
@@ -72,24 +72,31 @@ In the most simple case you need to do these steps:
|
||||
1. Copy `lv_conf_templ.h` as `lv_conf.h` next to `lvgl` and set at least `LV_HOR_RES`, `LV_VER_RES` and `LV_COLOR_DEPTH`.
|
||||
2. Call `lv_tick_inc(x)` every `x` milliseconds in a Timer or Task (`x` should be between 1 and 10)
|
||||
3. Call `lv_init()`
|
||||
4. Register a function which can **copy a pixel array** to an area of the screen:
|
||||
4. Create a buffer for LittlevGL
|
||||
```c
|
||||
static lv_disp_buf_t disp_buf;
|
||||
static lv_color_t buf[LV_HOR_RES_MAX * 10]; /*Declare a buffer for 10 lines*/
|
||||
v_disp_buf_init(&disp_buf1, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
```
|
||||
4. Implement and register a function which can **copy a pixel array** to an area of your diplay:
|
||||
```c
|
||||
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
disp_drv.disp_flush = disp_flush; /*Set your driver function*/
|
||||
disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
|
||||
disp_drv.buffer = &disp_buf; /*Assign the buffer to teh display*/
|
||||
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
|
||||
|
||||
void disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
|
||||
void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
int32_t x, y;
|
||||
for(y = y1; y <= y2; y++) {
|
||||
for(x = x1; x <= x2; x++) {
|
||||
sep_pixel(x, y, *color_p); /* Put a pixel to the display.*/
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
set_pixel(x, y, *color_p); /* Put a pixel to the display.*/
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
|
||||
lv_flush_ready(); /* Tell you are ready with the flushing*/
|
||||
lv_disp_flush_ready(disp); /* Tell you are ready with the flushing*/
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
CSRCS += lv_group.c
|
||||
CSRCS += lv_indev.c
|
||||
CSRCS += lv_disp.c
|
||||
CSRCS += lv_obj.c
|
||||
CSRCS += lv_refr.c
|
||||
CSRCS += lv_style.c
|
||||
CSRCS += lv_vdb.c
|
||||
CSRCS += lv_lang.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/lv_core
|
||||
|
||||
@@ -33,34 +33,82 @@
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get the number of areas in the buffer
|
||||
* @return number of invalid areas
|
||||
* Return with a pointer to the active screen
|
||||
* @param disp pointer to display which active screen should be get. (NULL to use the default screen)
|
||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
||||
*/
|
||||
uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp)
|
||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp)
|
||||
{
|
||||
return disp->inv_p;
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_scr_act: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->act_scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop (delete) the last 'num' invalidated areas from the buffer
|
||||
* @param num number of areas to delete
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num)
|
||||
void lv_disp_set_scr_act(lv_obj_t * scr)
|
||||
{
|
||||
lv_disp_t * d = lv_obj_get_disp(scr);
|
||||
|
||||
if(disp->inv_p < num) disp->inv_p = 0;
|
||||
else disp->inv_p -= num;
|
||||
d->act_scr = scr;
|
||||
|
||||
lv_obj_invalidate(scr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_layer_top: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->top_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen and the top layer)
|
||||
* @param disp pointer to display which sys. layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_layer_sys: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->sys_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
* @param scr pointer to a screen object to assign
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr)
|
||||
{
|
||||
lv_disp_t * old_disp = lv_scr_get_disp(scr);
|
||||
|
||||
if(old_disp == disp) {
|
||||
LV_LOG_WARN("lv_disp_assign_screen: tried to assign to the same screen")
|
||||
if(lv_obj_get_parent(scr) != NULL) {
|
||||
LV_LOG_WARN("lv_disp_assign_screen: try to assign a non-screen object");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_disp_t * old_disp = lv_obj_get_disp(scr);
|
||||
|
||||
if(old_disp == disp) return;
|
||||
|
||||
lv_ll_chg_list(&old_disp->scr_ll, &disp->scr_ll, scr);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,20 +27,41 @@ extern "C" {
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Return with a pointer to the active screen
|
||||
* @param disp pointer to display which active screen should be get. (NULL to use the default screen)
|
||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_scr_act(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Make a screen active
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_disp_set_scr_act(lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_top(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen and the top layer)
|
||||
* @param disp pointer to display which sys. layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Assign a screen to a display.
|
||||
* @param disp pointer to a display where to assign the screen
|
||||
* @param scr pointer to a screen object to assign
|
||||
*/
|
||||
void lv_disp_assign_screen(lv_disp_t * disp, lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Get the number of areas in the buffer
|
||||
* @return number of invalid areas
|
||||
*/
|
||||
uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Pop (delete) the last 'num' invalidated areas from the buffer
|
||||
* @param num number of areas to delete
|
||||
*/
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -126,12 +126,12 @@ void lv_indev_reset_lpr(lv_indev_t * indev)
|
||||
void lv_indev_enable(lv_hal_indev_type_t type, bool enable)
|
||||
{
|
||||
|
||||
// lv_indev_t * i = lv_indev_next(NULL);
|
||||
//
|
||||
// while(i) {
|
||||
// if(i->driver.type == type) i->proc.disabled = enable == false ? 1 : 0;
|
||||
// i = lv_indev_next(i);
|
||||
// }
|
||||
lv_indev_t * i = lv_indev_next(NULL);
|
||||
|
||||
while(i) {
|
||||
if(i->driver.type == type) i->proc.disabled = enable == false ? 1 : 0;
|
||||
i = lv_indev_next(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,7 +144,7 @@ void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj)
|
||||
if(indev->driver.type != LV_INDEV_TYPE_POINTER) return;
|
||||
|
||||
indev->cursor = cur_obj;
|
||||
lv_obj_set_parent(indev->cursor, lv_layer_sys(indev->driver.disp));
|
||||
lv_obj_set_parent(indev->cursor, lv_disp_get_layer_sys(indev->driver.disp));
|
||||
lv_obj_set_pos(indev->cursor, indev->proc.act_point.x, indev->proc.act_point.y);
|
||||
}
|
||||
|
||||
@@ -250,22 +250,19 @@ void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point)
|
||||
uint32_t lv_indev_get_inactive_time(const lv_indev_t * indev)
|
||||
{
|
||||
|
||||
//TODO
|
||||
// uint32_t t;
|
||||
//
|
||||
// if(indev) return t = lv_tick_elaps(indev->last_activity_time);
|
||||
//
|
||||
// lv_indev_t * i;
|
||||
// t = UINT16_MAX;
|
||||
// i = lv_indev_next(NULL);
|
||||
// while(i) {
|
||||
// t = LV_MATH_MIN(t, lv_tick_elaps(i->last_activity_time));
|
||||
// i = lv_indev_next(i);
|
||||
// }
|
||||
//
|
||||
// return t;
|
||||
uint32_t t;
|
||||
|
||||
return 0;
|
||||
if(indev) return t = lv_tick_elaps(indev->last_activity_time);
|
||||
|
||||
lv_indev_t * i;
|
||||
t = UINT16_MAX;
|
||||
i = lv_indev_next(NULL);
|
||||
while(i) {
|
||||
t = LV_MATH_MIN(t, lv_tick_elaps(i->last_activity_time));
|
||||
i = lv_indev_next(i);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -547,8 +544,8 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
*/
|
||||
static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
{
|
||||
i->proc.act_point.x = i->btn_points[data->btn].x;
|
||||
i->proc.act_point.y = i->btn_points[data->btn].y;
|
||||
i->proc.act_point.x = i->btn_points[data->btn_id].x;
|
||||
i->proc.act_point.y = i->btn_points[data->btn_id].y;
|
||||
|
||||
/*Still the same point is pressed*/
|
||||
if(i->proc.last_point.x == i->proc.act_point.x &&
|
||||
@@ -586,16 +583,16 @@ static void indev_proc_press(lv_indev_proc_t * proc)
|
||||
|
||||
/*If there is no last object then search*/
|
||||
if(proc->act_obj == NULL) {
|
||||
pr_obj = indev_search_obj(proc, lv_layer_sys(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_layer_top(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_scr_act(disp));
|
||||
pr_obj = indev_search_obj(proc, lv_disp_get_layer_sys(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_disp_get_layer_top(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_disp_get_scr_act(disp));
|
||||
}
|
||||
/*If there is last object but it is not dragged and not protected also search*/
|
||||
else if(proc->drag_in_prog == 0 &&
|
||||
lv_obj_is_protected(proc->act_obj, LV_PROTECT_PRESS_LOST) == false) {/*Now act_obj != NULL*/
|
||||
pr_obj = indev_search_obj(proc, lv_layer_sys(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_layer_top(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_scr_act(disp));
|
||||
pr_obj = indev_search_obj(proc, lv_disp_get_layer_sys(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_disp_get_layer_top(disp));
|
||||
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_disp_get_scr_act(disp));
|
||||
}
|
||||
/*If a dragable or a protected object was the last then keep it*/
|
||||
else {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "lv_indev.h"
|
||||
#include "lv_refr.h"
|
||||
#include "lv_group.h"
|
||||
#include "lv_disp.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
@@ -356,7 +357,7 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
|
||||
/*Remove the object from parent's children list*/
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
if(par == NULL) { /*It is a screen*/
|
||||
lv_disp_t * d = lv_scr_get_disp(obj);
|
||||
lv_disp_t * d = lv_obj_get_disp(obj);
|
||||
lv_ll_rem(&d->scr_ll, obj);
|
||||
} else {
|
||||
lv_ll_rem(&(par->child_ll), obj);
|
||||
@@ -415,10 +416,10 @@ void lv_obj_invalidate(const lv_obj_t * obj)
|
||||
|
||||
/*Invalidate the object only if it belongs to the 'LV_GC_ROOT(_lv_act_scr)'*/
|
||||
lv_obj_t * obj_scr = lv_obj_get_screen(obj);
|
||||
lv_disp_t * disp = lv_scr_get_disp(obj_scr);
|
||||
if(obj_scr == lv_scr_act(disp) ||
|
||||
obj_scr == lv_layer_top(disp)||
|
||||
obj_scr == lv_layer_sys(disp)) {
|
||||
lv_disp_t * disp = lv_obj_get_disp(obj_scr);
|
||||
if(obj_scr == lv_disp_get_scr_act(disp) ||
|
||||
obj_scr == lv_disp_get_layer_top(disp)||
|
||||
obj_scr == lv_disp_get_layer_sys(disp)) {
|
||||
/*Truncate recursively to the parents*/
|
||||
lv_area_t area_trunc;
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
@@ -449,23 +450,6 @@ void lv_obj_invalidate(const lv_obj_t * obj)
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
|
||||
/*--------------
|
||||
* Screen set
|
||||
*--------------*/
|
||||
/**
|
||||
* Load a new screen
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_scr_load(lv_obj_t * scr)
|
||||
{
|
||||
lv_disp_t * d = lv_scr_get_disp(scr);
|
||||
|
||||
d->act_scr = scr;
|
||||
|
||||
lv_obj_invalidate(scr);
|
||||
}
|
||||
|
||||
/*--------------------
|
||||
* Parent/children set
|
||||
*--------------------*/
|
||||
@@ -1302,55 +1286,6 @@ void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint1
|
||||
* Getter functions
|
||||
*======================*/
|
||||
|
||||
/*------------------
|
||||
* Screen get
|
||||
*-----------------*/
|
||||
|
||||
/**
|
||||
* Return with a pointer to the active screen
|
||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
||||
*/
|
||||
lv_obj_t * lv_scr_act(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_scr_act: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->act_scr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_layer_top(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_layer_top: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->top_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_layer_sys(lv_disp_t * disp)
|
||||
{
|
||||
if(!disp) disp = lv_disp_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("lv_layer_sys: no display registered to get its top layer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return disp->sys_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return with the screen of an object
|
||||
* @param obj pointer to an object
|
||||
@@ -1369,10 +1304,19 @@ lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj)
|
||||
return (lv_obj_t *)act_p;
|
||||
}
|
||||
|
||||
lv_disp_t * lv_scr_get_disp(lv_obj_t * scr)
|
||||
/**
|
||||
* Get the display of an object
|
||||
* @param scr pointer to an object
|
||||
* @return pointer the object's display
|
||||
*/
|
||||
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj)
|
||||
{
|
||||
lv_disp_t * d;
|
||||
const lv_obj_t * scr;
|
||||
|
||||
if(obj->par == NULL) scr = obj; /*`obj` is a screen*/
|
||||
else scr = lv_obj_get_screen(obj); /*get the screen of `obj`*/
|
||||
|
||||
lv_disp_t * d;
|
||||
LL_READ(LV_GC_ROOT(_lv_disp_ll), d) {
|
||||
lv_obj_t * s;
|
||||
LL_READ(d->scr_ll, s) {
|
||||
@@ -1384,14 +1328,6 @@ lv_disp_t * lv_scr_get_disp(lv_obj_t * scr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj)
|
||||
{
|
||||
lv_obj_t * scr = lv_obj_get_screen(obj);
|
||||
return lv_scr_get_disp(scr);
|
||||
}
|
||||
|
||||
/*---------------------
|
||||
* Parent/children get
|
||||
*--------------------*/
|
||||
|
||||
@@ -261,16 +261,6 @@ void lv_obj_invalidate(const lv_obj_t * obj);
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/*--------------
|
||||
* Screen set
|
||||
*--------------*/
|
||||
|
||||
/**
|
||||
* Load a new screen
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_scr_load(lv_obj_t * scr);
|
||||
|
||||
/*--------------------
|
||||
* Parent/children set
|
||||
*--------------------*/
|
||||
@@ -540,28 +530,6 @@ void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint1
|
||||
* Getter functions
|
||||
*======================*/
|
||||
|
||||
/*------------------
|
||||
* Screen get
|
||||
*-----------------*/
|
||||
|
||||
/**
|
||||
* Return with a pointer to the active screen
|
||||
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
|
||||
*/
|
||||
lv_obj_t * lv_scr_act(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @return pointer to the top layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_layer_top(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Return with the sys. layer. (Same on every screen and it is above the normal screen layer)
|
||||
* @return pointer to the sys layer object (transparent screen sized lv_obj)
|
||||
*/
|
||||
lv_obj_t * lv_layer_sys(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Return with the screen of an object
|
||||
* @param obj pointer to an object
|
||||
@@ -569,9 +537,11 @@ lv_obj_t * lv_layer_sys(lv_disp_t * disp);
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj);
|
||||
|
||||
|
||||
lv_disp_t * lv_scr_get_disp(lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Get the display of an object
|
||||
* @param scr pointer to an object
|
||||
* @return pointer the object's display
|
||||
*/
|
||||
lv_disp_t * lv_obj_get_disp(const lv_obj_t * obj);
|
||||
|
||||
/*---------------------
|
||||
|
||||
@@ -39,8 +39,6 @@ static void lv_refr_vdb_flush(void);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static void (*monitor_cb)(uint32_t, uint32_t); /*Monitor the rendering time*/
|
||||
static void (*round_cb)(lv_area_t *); /*If set then called to modify invalidated areas for special display controllers*/
|
||||
static uint32_t px_num;
|
||||
static lv_disp_t * disp_refr; /*Display being refreshed*/
|
||||
|
||||
@@ -103,7 +101,7 @@ void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
|
||||
/*The area is truncated to the screen*/
|
||||
if(suc != false) {
|
||||
if(round_cb) round_cb(&com_area);
|
||||
if(disp_refr->driver.rounder_cb) disp_refr->driver.rounder_cb(disp_refr, &com_area);
|
||||
|
||||
/*Save only if this area is not in one of the saved areas*/
|
||||
uint16_t i;
|
||||
@@ -122,29 +120,6 @@ void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a function to call after every refresh to announce the refresh time and the number of refreshed pixels
|
||||
* @param cb pointer to a callback function (void my_refr_cb(uint32_t time_ms, uint32_t px_num))
|
||||
* time_ms: refresh time in [ms]
|
||||
* px_num: not the drawn pixels but the number of affected pixels of the screen
|
||||
* (more pixels are drawn because of overlapping objects)
|
||||
*/
|
||||
void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t))
|
||||
{
|
||||
monitor_cb = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an area is invalidated to modify the coordinates of the area.
|
||||
* Special display controllers may require special coordinate rounding
|
||||
* @param cb pointer to the a function which will modify the area
|
||||
*/
|
||||
void lv_refr_set_round_cb(void(*cb)(lv_area_t *))
|
||||
{
|
||||
round_cb = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
@@ -180,8 +155,8 @@ static void lv_refr_task(void * param)
|
||||
/*If refresh happened ...*/
|
||||
if(disp_refr->inv_p != 0) {
|
||||
/*In true double buffered mode copy the refreshed areas to the new VDB to keep it up to date*/
|
||||
if(lv_disp_is_true_double_buffered(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(disp_refr);
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*Flush the content of the VDB*/
|
||||
lv_refr_vdb_flush();
|
||||
@@ -194,16 +169,17 @@ static void lv_refr_task(void * param)
|
||||
uint8_t * buf_act = (uint8_t *) vdb->buf_act;
|
||||
uint8_t * buf_ina = (uint8_t *) vdb->buf_act == vdb->buf1 ? vdb->buf2 : vdb->buf1;
|
||||
|
||||
lv_coord_t hres = lv_disp_get_hor_res(disp_refr);
|
||||
uint16_t a;
|
||||
for(a = 0; a < disp_refr->inv_p; a++) {
|
||||
if(disp_refr->inv_area_joined[a] == 0) {
|
||||
lv_coord_t y;
|
||||
uint32_t start_offs = ((disp_refr->driver.hor_res * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * LV_VDB_PX_BPP) >> 3;
|
||||
uint32_t line_length = (lv_area_get_width(&disp_refr->inv_areas[a]) * LV_VDB_PX_BPP) >> 3;
|
||||
uint32_t start_offs = (hres * disp_refr->inv_areas[a].y1 + disp_refr->inv_areas[a].x1) * sizeof(lv_color_t);
|
||||
uint32_t line_length = lv_area_get_width(&disp_refr->inv_areas[a]) * sizeof(lv_color_t);
|
||||
|
||||
for(y = disp_refr->inv_areas[a].y1; y <= disp_refr->inv_areas[a].y2; y++) {
|
||||
memcpy(buf_act + start_offs, buf_ina + start_offs, line_length);
|
||||
start_offs += (LV_HOR_RES * LV_VDB_PX_BPP) >> 3;
|
||||
start_offs += hres * sizeof(lv_color_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,8 +191,8 @@ static void lv_refr_task(void * param)
|
||||
disp_refr->inv_p = 0;
|
||||
|
||||
/*Call monitor cb if present*/
|
||||
if(monitor_cb != NULL) {
|
||||
monitor_cb(lv_tick_elaps(start), px_num);
|
||||
if(disp_refr->driver.monitor_cb) {
|
||||
disp_refr->driver.monitor_cb(disp_refr, lv_tick_elaps(start), px_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,7 +254,7 @@ static void lv_refr_areas(void)
|
||||
|
||||
lv_refr_area(&disp_refr->inv_areas[i]);
|
||||
|
||||
if(monitor_cb != NULL) px_num += lv_area_get_size(&disp_refr->inv_areas[i]);
|
||||
if(disp_refr->driver.monitor_cb) px_num += lv_area_get_size(&disp_refr->inv_areas[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,17 +266,17 @@ static void lv_refr_areas(void)
|
||||
static void lv_refr_area(const lv_area_t * area_p)
|
||||
{
|
||||
/*True double buffering: there are two screen sized buffers. Just redraw directly into a buffer*/
|
||||
if(lv_disp_is_true_double_buffered(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(disp_refr);
|
||||
if(lv_disp_is_true_double_buf(disp_refr)) {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
vdb->area.x1 = 0;
|
||||
vdb->area.x2 = LV_HOR_RES-1;
|
||||
vdb->area.x2 = lv_disp_get_hor_res(disp_refr) - 1;
|
||||
vdb->area.y1 = 0;
|
||||
vdb->area.y2 = LV_VER_RES - 1;
|
||||
vdb->area.y2 = lv_disp_get_ver_res(disp_refr) - 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
/*The buffer is smaller: refresh the area in parts*/
|
||||
else {
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(disp_refr);
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
/*Calculate the max row num*/
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
@@ -311,7 +287,7 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
if(max_row > h) max_row = h;
|
||||
|
||||
/*Round down the lines of VDB if rounding is added*/
|
||||
if(round_cb) {
|
||||
if(disp_refr->driver.rounder_cb) {
|
||||
lv_area_t tmp;
|
||||
tmp.x1 = 0;
|
||||
tmp.x2 = 0;
|
||||
@@ -321,7 +297,7 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
lv_coord_t y_tmp = max_row;
|
||||
do {
|
||||
tmp.y2 = y_tmp;
|
||||
round_cb(&tmp);
|
||||
disp_refr->driver.rounder_cb(disp_refr, &tmp);
|
||||
y_tmp --; /*Decrement the number of line until it is rounded to a smaller (or equal) value then the original. */
|
||||
} while(lv_area_get_height(&tmp) > max_row && y_tmp != 0);
|
||||
|
||||
@@ -368,10 +344,10 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
static void lv_refr_area_part(const lv_area_t * area_p)
|
||||
{
|
||||
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(disp_refr);
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp_refr);
|
||||
|
||||
/*In non double buffered mode, before rendering the next part wait until the previous image is flushed*/
|
||||
if(lv_disp_is_double_vdb(disp_refr) == false) {
|
||||
if(lv_disp_is_double_buf(disp_refr) == false) {
|
||||
while(vdb->flushing);
|
||||
}
|
||||
|
||||
@@ -383,18 +359,18 @@ static void lv_refr_area_part(const lv_area_t * area_p)
|
||||
lv_area_intersect(&start_mask, area_p, &vdb->area);
|
||||
|
||||
/*Get the most top object which is not covered by others*/
|
||||
top_p = lv_refr_get_top_obj(&start_mask, lv_scr_act(disp_refr));
|
||||
top_p = lv_refr_get_top_obj(&start_mask, lv_disp_get_scr_act(disp_refr));
|
||||
|
||||
/*Do the refreshing from the top object*/
|
||||
lv_refr_obj_and_children(top_p, &start_mask);
|
||||
|
||||
/*Also refresh top and sys layer unconditionally*/
|
||||
lv_refr_obj_and_children(lv_layer_top(disp_refr), &start_mask);
|
||||
lv_refr_obj_and_children(lv_layer_sys(disp_refr), &start_mask);
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_top(disp_refr), &start_mask);
|
||||
lv_refr_obj_and_children(lv_disp_get_layer_sys(disp_refr), &start_mask);
|
||||
|
||||
/* In true double buffered mode flush only once when all areas were rendered.
|
||||
* In normal mode flush after every area */
|
||||
if(lv_disp_is_true_double_buffered(disp_refr) == false) {
|
||||
if(lv_disp_is_true_double_buf(disp_refr) == false) {
|
||||
lv_refr_vdb_flush();
|
||||
}
|
||||
}
|
||||
@@ -445,7 +421,7 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
|
||||
/* Normally always will be a top_obj (at least the screen)
|
||||
* but in special cases (e.g. if the screen has alpha) it won't.
|
||||
* In this case use the screen directly */
|
||||
if(top_p == NULL) top_p = lv_scr_act(disp_refr);
|
||||
if(top_p == NULL) top_p = lv_disp_get_scr_act(disp_refr);
|
||||
|
||||
/*Refresh the top object and its children*/
|
||||
lv_refr_obj(top_p, mask_p);
|
||||
@@ -552,7 +528,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
|
||||
*/
|
||||
static void lv_refr_vdb_flush(void)
|
||||
{
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(lv_refr_get_disp_refreshing());
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(lv_refr_get_disp_refreshing());
|
||||
|
||||
/*In double buffered mode wait until the other buffer is flushed before flushing the current one*/
|
||||
if(vdb->buf1 && vdb->buf2) {
|
||||
@@ -563,7 +539,7 @@ static void lv_refr_vdb_flush(void)
|
||||
|
||||
/*Flush the rendered content to the display*/
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.disp_flush) disp->driver.disp_flush(disp, &vdb->area, vdb->buf_act);
|
||||
if(disp->driver.flush_cb) disp->driver.flush_cb(disp, &vdb->area, vdb->buf_act);
|
||||
|
||||
|
||||
if(vdb->buf1 && vdb->buf2) {
|
||||
|
||||
@@ -60,20 +60,6 @@ void lv_refr_now(void);
|
||||
*/
|
||||
void lv_inv_area(lv_disp_t * disp, const lv_area_t * area_p);
|
||||
|
||||
|
||||
/**
|
||||
* Set a function to call after every refresh to announce the refresh time and the number of refreshed pixels
|
||||
* @param cb pointer to a callback function (void my_refr_cb(uint32_t time_ms, uint32_t px_num))
|
||||
*/
|
||||
void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t));
|
||||
|
||||
/**
|
||||
* Called when an area is invalidated to modify the coordinates of the area.
|
||||
* Special display controllers may require special coordinate rounding
|
||||
* @param cb pointer to the a function which will modify the area
|
||||
*/
|
||||
void lv_refr_set_round_cb(void(*cb)(lv_area_t*));
|
||||
|
||||
/**
|
||||
* Get the number of areas in the buffer
|
||||
* @return number of invalid areas
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
CSRCS += lv_draw_vbasic.c
|
||||
CSRCS += lv_draw_rbasic.c
|
||||
CSRCS += lv_draw_basic.c
|
||||
CSRCS += lv_draw.c
|
||||
CSRCS += lv_draw_rect.c
|
||||
CSRCS += lv_draw_label.c
|
||||
|
||||
@@ -79,15 +79,15 @@ void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(disp);
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
uint32_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
|
||||
/*Make the coordinates relative to VDB*/
|
||||
x -= vdb->area.x1;
|
||||
y -= vdb->area.y1;
|
||||
|
||||
if(disp->driver.vdb_wr) {
|
||||
disp->driver.vdb_wr((uint8_t *)vdb->buf_act, vdb_width, x, y, color, opa);
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(disp, (uint8_t *)vdb->buf_act, vdb_width, x, y, color, opa);
|
||||
} else {
|
||||
lv_color_t * vdb_px_p = vdb->buf_act;
|
||||
vdb_px_p += y * vdb_width + x;
|
||||
@@ -129,7 +129,7 @@ void lv_draw_fill(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
if(union_ok == false) return;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(disp);
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
lv_area_t vdb_rel_a; /*Stores relative coordinates on vdb*/
|
||||
vdb_rel_a.x1 = res_a.x1 - vdb->area.x1;
|
||||
@@ -290,7 +290,7 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
pos_y + letter_h < mask_p->y1 || pos_y > mask_p->y2) return;
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(disp);
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
|
||||
lv_color_t * vdb_buf_tmp = vdb->buf_act;
|
||||
@@ -335,8 +335,8 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p,
|
||||
(uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
}
|
||||
|
||||
if(disp->driver.vdb_wr) {
|
||||
disp->driver.vdb_wr((uint8_t *)vdb->buf_act, vdb_width,
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(disp, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1,
|
||||
color, px_opa);
|
||||
} else {
|
||||
@@ -409,7 +409,7 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_vdb(disp);
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
|
||||
/*Stores coordinates relative to the current VDB*/
|
||||
masked_a.x1 = masked_a.x1 - vdb->area.x1;
|
||||
@@ -429,12 +429,12 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
if(chroma_key == false && alpha_byte == false && opa == LV_OPA_COVER && recolor_opa == LV_OPA_TRANSP) {
|
||||
|
||||
/*Use the custom VDB write function is exists*/
|
||||
if(disp->driver.vdb_wr) {
|
||||
if(disp->driver.set_px_cb) {
|
||||
lv_coord_t col;
|
||||
for(row = masked_a.y1; row <= masked_a.y2; row++) {
|
||||
for(col = 0; col < map_useful_w; col++) {
|
||||
lv_color_t px_color = *((lv_color_t *)&map_p[(uint32_t)col * px_size_byte]);
|
||||
disp->driver.vdb_wr((uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, px_color, opa);
|
||||
disp->driver.set_px_cb(disp, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, px_color, opa);
|
||||
}
|
||||
map_p += map_width * px_size_byte; /*Next row on the map*/
|
||||
}
|
||||
@@ -496,8 +496,8 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
|
||||
}
|
||||
/*Handle custom VDB write is present*/
|
||||
if(disp->driver.vdb_wr) {
|
||||
disp->driver.vdb_wr((uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, recolored_px, opa_result);
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(disp, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, recolored_px, opa_result);
|
||||
}
|
||||
/*Normal native VDB write*/
|
||||
else {
|
||||
@@ -506,8 +506,8 @@ void lv_draw_map(const lv_area_t * cords_p, const lv_area_t * mask_p,
|
||||
}
|
||||
} else {
|
||||
/*Handle custom VDB write is present*/
|
||||
if(disp->driver.vdb_wr) {
|
||||
disp->driver.vdb_wr((uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, px_color, opa_result);
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(disp, (uint8_t *)vdb->buf_act, vdb_width, col + masked_a.x1, row, px_color, opa_result);
|
||||
}
|
||||
/*Normal native VDB write*/
|
||||
else {
|
||||
@@ -568,10 +568,10 @@ static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_
|
||||
lv_coord_t mem_width = lv_area_get_width(mem_area);
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.vdb_wr) {
|
||||
if(disp->driver.set_px_cb) {
|
||||
for(col = fill_area->x1; col <= fill_area->x2; col++) {
|
||||
for(row = fill_area->y1; row <= fill_area->y2; row++) {
|
||||
disp->driver.vdb_wr((uint8_t *)mem, mem_width, col, row, color, opa);
|
||||
disp->driver.set_px_cb(disp, (uint8_t *)mem, mem_width, col, row, color, opa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_ATTRIBUTE_FLUSH_READY
|
||||
# define LV_ATTRIBUTE_FLUSH_READY
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -59,7 +56,7 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
{
|
||||
memset(driver, 0, sizeof(lv_disp_drv_t));
|
||||
|
||||
driver->disp_flush = NULL;
|
||||
driver->flush_cb = NULL;
|
||||
driver->hor_res = LV_HOR_RES_MAX;
|
||||
driver->ver_res = LV_VER_RES_MAX;
|
||||
driver->buffer = NULL;
|
||||
@@ -69,7 +66,7 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
|
||||
driver->mem_fill = NULL;
|
||||
#endif
|
||||
|
||||
driver->vdb_wr = NULL;
|
||||
driver->set_px_cb = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,54 +116,48 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
|
||||
if(disp_def == NULL) disp_def = disp;
|
||||
|
||||
lv_disp_t * disp_def_tmp = disp_def;
|
||||
disp_def = disp; /*Temporarily change the default screen to create the default screens on the new display*/
|
||||
|
||||
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
|
||||
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
|
||||
lv_obj_set_style(disp->top_layer, &lv_style_transp);
|
||||
lv_obj_set_style(disp->sys_layer, &lv_style_transp);
|
||||
|
||||
lv_disp_assign_screen(disp, disp->act_scr);
|
||||
lv_disp_assign_screen(disp, disp->top_layer);
|
||||
lv_disp_assign_screen(disp, disp->sys_layer);
|
||||
|
||||
disp->inv_p = 0;
|
||||
disp->vdb_act = 0;
|
||||
disp->vdb_flushing = 0;
|
||||
|
||||
lv_obj_invalidate(disp->act_scr);
|
||||
|
||||
disp_def = disp_def_tmp; /*Revert the default display*/
|
||||
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next display.
|
||||
* @param disp pointer to the current display. NULL to initialize.
|
||||
* @return the next display or NULL if no more. Give the first display when the parameter is NULL
|
||||
* Set a default screen. The new screens will be created on it by default.
|
||||
* @param disp pointer to a display
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_next(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) return lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
else return lv_ll_get_next(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
}
|
||||
|
||||
|
||||
void lv_disp_set_default(lv_disp_t * disp)
|
||||
{
|
||||
disp_def = disp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the default display
|
||||
* @return pointer to the default display
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_default(void)
|
||||
{
|
||||
return disp_def;
|
||||
}
|
||||
|
||||
lv_disp_buf_t * lv_disp_get_vdb(lv_disp_t * disp)
|
||||
{
|
||||
return disp->driver.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the horizontal resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the horizontal resolution of the display
|
||||
*/
|
||||
lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
@@ -175,7 +166,11 @@ lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp)
|
||||
else return disp->driver.hor_res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the vertical resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the vertical resolution of the display
|
||||
*/
|
||||
lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) disp = lv_disp_get_default();
|
||||
@@ -184,19 +179,6 @@ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp)
|
||||
else return disp->driver.ver_res;
|
||||
}
|
||||
|
||||
bool lv_disp_is_double_vdb(lv_disp_t * disp)
|
||||
{
|
||||
if(disp->driver.buffer->buf1 && disp->driver.buffer->buf2) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool lv_disp_is_true_double_buffered(lv_disp_t * disp)
|
||||
{
|
||||
if(lv_disp_is_double_vdb(disp) && disp->driver.buffer->size == disp->driver.hor_res * disp->driver.ver_res) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call in the display driver's `flush` function when the flushing is finished
|
||||
*/
|
||||
@@ -211,7 +193,77 @@ LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_t * disp)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the next display.
|
||||
* @param disp pointer to the current display. NULL to initialize.
|
||||
* @return the next display or NULL if no more. Give the first display when the parameter is NULL
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_next(lv_disp_t * disp)
|
||||
{
|
||||
if(disp == NULL) return lv_ll_get_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
else return lv_ll_get_next(&LV_GC_ROOT(_lv_disp_ll), disp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the internal buffer of a display
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the internal buffers
|
||||
*/
|
||||
lv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp)
|
||||
{
|
||||
return disp->driver.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of areas in the buffer
|
||||
* @return number of invalid areas
|
||||
*/
|
||||
uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp)
|
||||
{
|
||||
return disp->inv_p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop (delete) the last 'num' invalidated areas from the buffer
|
||||
* @param num number of areas to delete
|
||||
*/
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num)
|
||||
{
|
||||
|
||||
if(disp->inv_p < num) disp->inv_p = 0;
|
||||
else disp->inv_p -= num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
bool lv_disp_is_double_buf(lv_disp_t * disp)
|
||||
{
|
||||
if(disp->driver.buffer->buf1 && disp->driver.buffer->buf2) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and `size` is screen sized)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
bool lv_disp_is_true_double_buf(lv_disp_t * disp)
|
||||
{
|
||||
uint32_t scr_size = disp->driver.hor_res * disp->driver.ver_res;
|
||||
|
||||
if(lv_disp_is_double_buf(disp) &&
|
||||
disp->driver.buffer->size == scr_size) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ extern "C" {
|
||||
#define LV_INV_BUF_SIZE 32 /*Buffer size for invalid areas */
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_FLUSH_READY
|
||||
# define LV_ATTRIBUTE_FLUSH_READY
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -53,28 +57,42 @@ typedef struct
|
||||
* Display Driver structure to be registered by HAL
|
||||
*/
|
||||
typedef struct _disp_drv_t {
|
||||
int user_data;
|
||||
|
||||
/*Horizontal and vertical resolution*/
|
||||
lv_coord_t hor_res;
|
||||
|
||||
lv_coord_t ver_res;
|
||||
|
||||
/* Pointer to a buffer initialized with `lv_disp_buf_init()`.
|
||||
* LittlevGL will use this buffer(s) to draw the screens contents */
|
||||
lv_disp_buf_t * buffer;
|
||||
|
||||
/*Write the internal buffer (VDB) to the display. 'lv_flush_ready()' has to be called when finished*/
|
||||
void (*disp_flush)(struct _disp_t * disp, const lv_area_t * area, lv_color_t * color_p);
|
||||
/* MANDATORY: Write the internal buffer (VDB) to the display. 'lv_flush_ready()' has to be called when finished */
|
||||
void (*flush_cb)(struct _disp_t * disp, const lv_area_t * area, lv_color_t * color_p);
|
||||
lv_disp_user_data_t flush_user_data;
|
||||
|
||||
/* OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the number of flushed pixels */
|
||||
void (*monitor_cb)(struct _disp_t * disp, uint32_t time, uint32_t px);
|
||||
lv_disp_user_data_t monitor_user_data;
|
||||
|
||||
/* OPTIONAL: Extend the invalidated areas to match with the display drivers requirements
|
||||
* E.g. round `y` to, 8, 16 ..) on a monochrome display*/
|
||||
void (*rounder_cb)(struct _disp_t * disp, lv_area_t * area);
|
||||
lv_disp_user_data_t rounder_user_data;
|
||||
|
||||
/* OPTIONAL: Set a pixel in a buffer according to the special requirements of the display
|
||||
* Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales
|
||||
* Note: Much slower then drawing with supported color formats. */
|
||||
void (*set_px_cb)(struct _disp_t * disp, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
lv_disp_user_data_t set_px_user_data;
|
||||
|
||||
/*Optional interface functions to use GPU*/
|
||||
#if USE_LV_GPU
|
||||
/*Blend two memories using opacity (GPU only)*/
|
||||
/*OPTIONAL: Blend two memories using opacity (GPU only)*/
|
||||
void (*mem_blend)(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
|
||||
|
||||
/*Fill a memory with a color (GPU only)*/
|
||||
/*OPTIONAL: Fill a memory with a color (GPU only)*/
|
||||
void (*mem_fill)(lv_color_t * dest, uint32_t length, lv_color_t color);
|
||||
#endif
|
||||
|
||||
/*Optional: Set a pixel in a buffer according to the requirements of the display*/
|
||||
void (*vdb_wr)(uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
|
||||
} lv_disp_drv_t;
|
||||
|
||||
struct _lv_obj_t;
|
||||
@@ -88,9 +106,6 @@ typedef struct _disp_t {
|
||||
lv_area_t inv_areas[LV_INV_BUF_SIZE];
|
||||
uint8_t inv_area_joined[LV_INV_BUF_SIZE];
|
||||
uint32_t inv_p :10;
|
||||
uint32_t orientation :2;
|
||||
uint32_t vdb_flushing :1;
|
||||
uint32_t vdb_act :1;
|
||||
} lv_disp_t;
|
||||
|
||||
/**********************
|
||||
@@ -103,15 +118,7 @@ typedef struct _disp_t {
|
||||
* After it you can set the fields.
|
||||
* @param driver pointer to driver variable to initialize
|
||||
*/
|
||||
void lv_disp_drv_init(lv_disp_drv_t *driver);
|
||||
|
||||
/**
|
||||
* Register an initialized display driver.
|
||||
* Automatically set the first display as active.
|
||||
* @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)
|
||||
* @return pointer to the new display or NULL on error
|
||||
*/
|
||||
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t *driver);
|
||||
void lv_disp_drv_init(lv_disp_drv_t * driver);
|
||||
|
||||
|
||||
/**
|
||||
@@ -131,12 +138,46 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t *driver);
|
||||
*/
|
||||
void lv_disp_buf_init(lv_disp_buf_t * disp_buf, void * buf1, void * buf2, uint32_t size);
|
||||
|
||||
/**
|
||||
* Register an initialized display driver.
|
||||
* Automatically set the first display as active.
|
||||
* @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)
|
||||
* @return pointer to the new display or NULL on error
|
||||
*/
|
||||
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver);
|
||||
|
||||
/**
|
||||
* Set a default screen. The new screens will be created on it by default.
|
||||
* @param disp pointer to a display
|
||||
*/
|
||||
void lv_disp_set_default(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get the default display
|
||||
* @return pointer to the default display
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_default(void);
|
||||
|
||||
lv_disp_buf_t * lv_disp_get_vdb(lv_disp_t * disp);
|
||||
/**
|
||||
* Get the horizontal resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the horizontal resolution of the display
|
||||
*/
|
||||
lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get the vertical resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the vertical resolution of the display
|
||||
*/
|
||||
lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Call in the display driver's `flush` function when the flushing is finished
|
||||
*/
|
||||
LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_t * disp);
|
||||
|
||||
|
||||
/**
|
||||
* Get the next display.
|
||||
* @param disp pointer to the current display. NULL to initialize.
|
||||
@@ -144,13 +185,39 @@ lv_disp_buf_t * lv_disp_get_vdb(lv_disp_t * disp);
|
||||
*/
|
||||
lv_disp_t * lv_disp_get_next(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Get the internal buffer of a display
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the internal buffers
|
||||
*/
|
||||
lv_disp_buf_t * lv_disp_get_buf(lv_disp_t * disp);
|
||||
|
||||
lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp);
|
||||
lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp);
|
||||
/**
|
||||
* Get the number of areas in the buffer
|
||||
* @return number of invalid areas
|
||||
*/
|
||||
uint16_t lv_disp_get_inv_buf_size(lv_disp_t * disp);
|
||||
|
||||
bool lv_disp_is_double_vdb(lv_disp_t * disp);
|
||||
/**
|
||||
* Pop (delete) the last 'num' invalidated areas from the buffer
|
||||
* @param num number of areas to delete
|
||||
*/
|
||||
void lv_disp_pop_from_inv_buf(lv_disp_t * disp, uint16_t num);
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's double buffered (both `buf1` and `buf2` are set)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
bool lv_disp_is_double_buf(lv_disp_t * disp);
|
||||
|
||||
/**
|
||||
* Check the driver configuration if it's TRUE double buffered (both `buf1` and `buf2` are set and `size` is screen sized)
|
||||
* @param disp pointer to to display to check
|
||||
* @return true: double buffered; false: not double buffered
|
||||
*/
|
||||
bool lv_disp_is_true_double_buf(lv_disp_t * disp);
|
||||
|
||||
bool lv_disp_is_true_double_buffered(lv_disp_t * disp);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -50,10 +50,9 @@
|
||||
*/
|
||||
void lv_indev_drv_init(lv_indev_drv_t * driver)
|
||||
{
|
||||
driver->read = NULL;
|
||||
memset(driver, 0, sizeof(lv_indev_drv_t));
|
||||
|
||||
driver->type = LV_INDEV_TYPE_NONE;
|
||||
driver->disp = NULL;
|
||||
driver->user_data = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,13 +109,11 @@ bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
bool cont = false;
|
||||
|
||||
memset(data, 0, sizeof(lv_indev_data_t));
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
|
||||
if(indev->driver.read) {
|
||||
data->user_data = indev->driver.user_data;
|
||||
if(indev->driver.read_cb) {
|
||||
|
||||
LV_LOG_TRACE("idnev read started");
|
||||
cont = indev->driver.read(data);
|
||||
cont = indev->driver.read_cb(indev, data);
|
||||
LV_LOG_TRACE("idnev read finished");
|
||||
} else {
|
||||
LV_LOG_WARN("indev function registered");
|
||||
|
||||
@@ -15,6 +15,12 @@ extern "C" {
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "../lv_misc/lv_area.h"
|
||||
@@ -28,6 +34,7 @@ extern "C" {
|
||||
**********************/
|
||||
|
||||
struct _disp_t;
|
||||
struct _lv_indev_t;
|
||||
|
||||
/*Possible input device types*/
|
||||
enum {
|
||||
@@ -48,22 +55,23 @@ typedef uint8_t lv_indev_state_t;
|
||||
|
||||
/*Data type when an input device is read */
|
||||
typedef struct {
|
||||
void *user_data; /*'lv_indev_drv_t.priv' for this driver*/
|
||||
union {
|
||||
lv_point_t point; /*For LV_INDEV_TYPE_POINTER the currently pressed point*/
|
||||
uint32_t key; /*For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
|
||||
uint32_t btn; /*For LV_INDEV_TYPE_BUTTON the currently pressed button*/
|
||||
int16_t enc_diff; /*For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
|
||||
lv_point_t point; /*For LV_INDEV_TYPE_POINTER the currently pressed point*/
|
||||
uint32_t key; /*For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
|
||||
uint32_t btn_id; /*For LV_INDEV_TYPE_BUTTON the currently pressed button*/
|
||||
int16_t enc_diff; /*For LV_INDEV_TYPE_ENCODER number of steps since the previous read*/
|
||||
};
|
||||
|
||||
lv_indev_state_t state; /*LV_INDEV_STATE_REL or LV_INDEV_STATE_PR*/
|
||||
|
||||
} lv_indev_data_t;
|
||||
|
||||
/*Initialized by the user and registered by 'lv_indev_add()'*/
|
||||
typedef struct {
|
||||
lv_hal_indev_type_t type; /*Input device type*/
|
||||
bool (*read)(lv_indev_data_t *data); /*Function pointer to read data. Return 'true' if there is still data to be read (buffered)*/
|
||||
lv_hal_indev_type_t type; /*Input device type*/
|
||||
bool (*read_cb)(struct _lv_indev_t * indev, lv_indev_data_t *data); /*Function pointer to read_cb data. Return 'true' if there is still data to be read_cb (buffered)*/
|
||||
lv_indev_user_data_t read_user_data; /*Pointer to user defined data, passed in 'lv_indev_data_t' on read*/
|
||||
struct _disp_t * disp;
|
||||
void *user_data; /*Pointer to user defined data, passed in 'lv_indev_data_t' on read*/
|
||||
} lv_indev_drv_t;
|
||||
|
||||
struct _lv_obj_t;
|
||||
@@ -100,8 +108,6 @@ typedef struct _lv_indev_proc_t {
|
||||
uint8_t disabled :1;
|
||||
} lv_indev_proc_t;
|
||||
|
||||
struct _lv_indev_t;
|
||||
|
||||
typedef void (*lv_indev_feedback_t)(struct _lv_indev_t *, uint8_t);
|
||||
|
||||
struct _lv_obj_t;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#if USE_LV_WIN != 0
|
||||
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_core/lv_disp.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -70,7 +71,7 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Init the new window object*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_t * disp = lv_obj_get_disp(new_win);
|
||||
lv_disp_t * disp = lv_obj_get_disp(new_win);
|
||||
lv_coord_t hres = lv_disp_get_hor_res(disp);
|
||||
lv_coord_t vres = lv_disp_get_ver_res(disp);
|
||||
lv_obj_set_size(new_win, hres, vres);
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
**********************/
|
||||
static void disp_init(void);
|
||||
|
||||
static void disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
|
||||
static void disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
|
||||
static void disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
|
||||
static void disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p);
|
||||
#if USE_LV_GPU
|
||||
static void mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
|
||||
static void mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color);
|
||||
@@ -51,6 +49,41 @@ void lv_port_disp_init(void)
|
||||
* -----------------------*/
|
||||
disp_init();
|
||||
|
||||
/*-----------------------------
|
||||
* Create a buffer for drawing
|
||||
*----------------------------*/
|
||||
|
||||
/* LittlevGL requires a buffer where it draw the objects. The buffer's has to be greater than 1 display row
|
||||
*
|
||||
* There are three buffering configurations:
|
||||
* 1. Create ONE buffer some rows: LittlevGL will draw the display's content here and writes it to your display
|
||||
* 2. Create TWO buffer some rows: LittlevGL will draw the display's content to a buffer and writes it your display.
|
||||
* You should use DMA to write the buffer's content to the display.
|
||||
* It will enable LittlevGL to draw the next part of the screen to the other buffer while
|
||||
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
|
||||
* 3. Create TWO screen buffer: Similar to 2) but the buffer have to be screen sized. When LittlevGL is ready it will give the
|
||||
* whole frame to display. This way you only need to change the frame buffer's address instead of
|
||||
* copying the pixels.
|
||||
* */
|
||||
|
||||
/* Example for 1) */
|
||||
static lv_disp_buf_t disp_buf_1;
|
||||
static lv_color_t buf1_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/
|
||||
lv_disp_buf_init(&disp_buf_1, buf1_1, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
|
||||
/* Example for 2) */
|
||||
static lv_disp_buf_t disp_buf_2;
|
||||
static lv_color_t buf2_1[LV_HOR_RES_MAX * 10]; /*A buffer for 10 rows*/
|
||||
static lv_color_t buf2_2[LV_HOR_RES_MAX * 10]; /*An other buffer for 10 rows*/
|
||||
lv_disp_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
|
||||
|
||||
/* Example for 3) */
|
||||
static lv_disp_buf_t disp_buf_3;
|
||||
static lv_color_t buf3_1[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*A screen sized buffer*/
|
||||
static lv_color_t buf3_2[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*An other screen sized buffer*/
|
||||
lv_disp_buf_init(&disp_buf_3, buf3_1, buf3_2, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/
|
||||
|
||||
|
||||
/*-----------------------------------
|
||||
* Register the display in LittlevGL
|
||||
*----------------------------------*/
|
||||
@@ -60,14 +93,8 @@ void lv_port_disp_init(void)
|
||||
|
||||
/*Set up the functions to access to your display*/
|
||||
|
||||
/*Used in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
|
||||
disp_drv.disp_flush = disp_flush;
|
||||
|
||||
/*Used in unbuffered mode (LV_VDB_SIZE == 0 in lv_conf.h)*/
|
||||
disp_drv.disp_fill = disp_fill;
|
||||
|
||||
/*Used in unbuffered mode (LV_VDB_SIZE == 0 in lv_conf.h)*/
|
||||
disp_drv.disp_map = disp_map;
|
||||
/*Used to copy the buffer's content to the display*/
|
||||
disp_drv.flush_cb = disp_flush;
|
||||
|
||||
#if USE_LV_GPU
|
||||
/*Optionally add functions to access the GPU. (Only in buffered mode, LV_VDB_SIZE != 0)*/
|
||||
@@ -95,16 +122,15 @@ static void disp_init(void)
|
||||
|
||||
/* Flush the content of the internal buffer the specific area on the display
|
||||
* You can use DMA or any hardware acceleration to do this operation in the background but
|
||||
* 'lv_flush_ready()' has to be called when finished
|
||||
* This function is required only when LV_VDB_SIZE != 0 in lv_conf.h*/
|
||||
static void disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
|
||||
* 'lv_disp_flush_ready()' has to be called when finished. */
|
||||
static void disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
|
||||
{
|
||||
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
|
||||
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
for(y = y1; y <= y2; y++) {
|
||||
for(x = x1; x <= x2; x++) {
|
||||
for(y = area->y1; y <= area->y2; y++) {
|
||||
for(x = area->x1; x <= area->x2; x++) {
|
||||
/* Put a pixel to the display. For example: */
|
||||
/* put_px(x, y, *color_p)*/
|
||||
color_p++;
|
||||
@@ -113,46 +139,10 @@ static void disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_
|
||||
|
||||
/* IMPORTANT!!!
|
||||
* Inform the graphics library that you are ready with the flushing*/
|
||||
lv_flush_ready();
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
|
||||
/* Write a pixel array (called 'map') to the a specific area on the display
|
||||
* This function is required only when LV_VDB_SIZE == 0 in lv_conf.h*/
|
||||
static void disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
|
||||
{
|
||||
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
|
||||
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
for(y = y1; y <= y2; y++) {
|
||||
for(x = x1; x <= x2; x++) {
|
||||
/* Put a pixel to the display. For example: */
|
||||
/* put_px(x, y, *color_p)*/
|
||||
color_p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Write a pixel array (called 'map') to the a specific area on the display
|
||||
* This function is required only when LV_VDB_SIZE == 0 in lv_conf.h*/
|
||||
static void disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
|
||||
{
|
||||
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
|
||||
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
for(y = y1; y <= y2; y++) {
|
||||
for(x = x1; x <= x2; x++) {
|
||||
/* Put a pixel to the display. For example: */
|
||||
/* put_px(x, y, *color)*/
|
||||
}
|
||||
}
|
||||
|
||||
(void)color; /*Just to avid warnings*/
|
||||
}
|
||||
|
||||
/*OPTIONAL: GPU INTERFACE*/
|
||||
#if USE_LV_GPU
|
||||
|
||||
|
||||
@@ -24,25 +24,25 @@
|
||||
**********************/
|
||||
|
||||
static void touchpad_init(void);
|
||||
static bool touchpad_read(lv_indev_data_t * data);
|
||||
static bool touchpad_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
static bool touchpad_is_pressed(void);
|
||||
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);
|
||||
|
||||
static void mouse_init(void);
|
||||
static bool mouse_read(lv_indev_data_t * data);
|
||||
static bool mouse_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
static bool mouse_is_pressed(void);
|
||||
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);
|
||||
|
||||
static void keypad_init(void);
|
||||
static bool keypad_read(lv_indev_data_t * data);
|
||||
static bool keypad_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
static uint32_t keypad_get_key(void);
|
||||
|
||||
static void encoder_init(void);
|
||||
static bool encoder_read(lv_indev_data_t * data);
|
||||
static bool encoder_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
static void encoder_handler(void);
|
||||
|
||||
static void button_init(void);
|
||||
static bool button_read(lv_indev_data_t * data);
|
||||
static bool button_read(lv_indev_t * indev, lv_indev_data_t * data);
|
||||
static int8_t button_get_pressed_id(void);
|
||||
static bool button_is_pressed(uint8_t id);
|
||||
|
||||
@@ -92,7 +92,7 @@ void lv_port_indev_init(void)
|
||||
/*Register a touchpad input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read = touchpad_read;
|
||||
indev_drv.read_cb = touchpad_read;
|
||||
indev_touchpad = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/*------------------
|
||||
@@ -105,11 +105,11 @@ void lv_port_indev_init(void)
|
||||
/*Register a mouse input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read = mouse_read;
|
||||
indev_drv.read_cb = mouse_read;
|
||||
indev_mouse = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/*Set cursor. For simplicity set a HOME symbol now.*/
|
||||
lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act(NULL), NULL);
|
||||
lv_obj_t * mouse_cursor = lv_img_create(lv_disp_get_scr_act(NULL), NULL);
|
||||
lv_img_set_src(mouse_cursor, SYMBOL_HOME);
|
||||
lv_indev_set_cursor(indev_mouse, mouse_cursor);
|
||||
|
||||
@@ -123,7 +123,7 @@ void lv_port_indev_init(void)
|
||||
/*Register a keypad input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
|
||||
indev_drv.read = keypad_read;
|
||||
indev_drv.read_cb = keypad_read;
|
||||
indev_keypad = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
|
||||
@@ -141,7 +141,7 @@ void lv_port_indev_init(void)
|
||||
/*Register a encoder input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
|
||||
indev_drv.read = encoder_read;
|
||||
indev_drv.read_cb = encoder_read;
|
||||
indev_encoder = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
|
||||
@@ -159,7 +159,7 @@ void lv_port_indev_init(void)
|
||||
/*Register a button input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_BUTTON;
|
||||
indev_drv.read = button_read;
|
||||
indev_drv.read_cb = button_read;
|
||||
indev_button = lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/*Assign buttons to points on the screen*/
|
||||
@@ -187,7 +187,7 @@ static void touchpad_init(void)
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the touchpad */
|
||||
static bool touchpad_read(lv_indev_data_t * data)
|
||||
static bool touchpad_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
static lv_coord_t last_x = 0;
|
||||
static lv_coord_t last_y = 0;
|
||||
@@ -237,7 +237,7 @@ static void mouse_init(void)
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the mouse */
|
||||
static bool mouse_read(lv_indev_data_t * data)
|
||||
static bool mouse_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
/*Get the current x and y coordinates*/
|
||||
mouse_get_xy(&data->point.x, &data->point.y);
|
||||
@@ -281,7 +281,7 @@ static void keypad_init(void)
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the mouse */
|
||||
static bool keypad_read(lv_indev_data_t * data)
|
||||
static bool keypad_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
static uint32_t last_key = 0;
|
||||
|
||||
@@ -342,7 +342,7 @@ static void encoder_init(void)
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the encoder */
|
||||
static bool encoder_read(lv_indev_data_t * data)
|
||||
static bool encoder_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
|
||||
data->enc_diff = encoder_diff;
|
||||
@@ -373,7 +373,7 @@ static void button_init(void)
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the button */
|
||||
static bool button_read(lv_indev_data_t * data)
|
||||
static bool button_read(lv_indev_t * indev, lv_indev_data_t * data)
|
||||
{
|
||||
|
||||
static uint8_t last_btn = 0;
|
||||
@@ -389,7 +389,7 @@ static bool button_read(lv_indev_data_t * data)
|
||||
}
|
||||
|
||||
/*Save the last pressed button's ID*/
|
||||
data->btn = last_btn;
|
||||
data->btn_id = last_btn;
|
||||
|
||||
/*Return `false` because we are not buffering and no more data to read*/
|
||||
return false;
|
||||
|
||||
@@ -14,10 +14,10 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
/*Current version of LittlevGL*/
|
||||
#define LVGL_VERSION_MAJOR 5
|
||||
#define LVGL_VERSION_MINOR 3
|
||||
#define LVGL_VERSION_MAJOR 6
|
||||
#define LVGL_VERSION_MINOR 0
|
||||
#define LVGL_VERSION_PATCH 0
|
||||
#define LVGL_VERSION_INFO ""
|
||||
#define LVGL_VERSION_INFO "dev"
|
||||
|
||||
|
||||
/*********************
|
||||
|
||||
Reference in New Issue
Block a user