1 /**
2 * @file lv_disp.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "../display/lv_display_private.h"
10 #include "../misc/lv_event_private.h"
11 #include "../misc/lv_anim_private.h"
12 #include "../draw/lv_draw_private.h"
13 #include "../core/lv_obj_private.h"
14 #include "lv_display.h"
15 #include "../misc/lv_math.h"
16 #include "../core/lv_refr_private.h"
17 #include "../stdlib/lv_string.h"
18 #include "../themes/lv_theme.h"
19 #include "../core/lv_global.h"
20 #include "../others/sysmon/lv_sysmon.h"
21
22 #if LV_USE_DRAW_SW
23 #include "../draw/sw/lv_draw_sw.h"
24 #endif
25
26 /*********************
27 * DEFINES
28 *********************/
29 #define disp_def LV_GLOBAL_DEFAULT()->disp_default
30 #define disp_ll_p &(LV_GLOBAL_DEFAULT()->disp_ll)
31
32 /**********************
33 * TYPEDEFS
34 **********************/
35
36 /**********************
37 * STATIC PROTOTYPES
38 **********************/
39 static lv_obj_tree_walk_res_t invalidate_layout_cb(lv_obj_t * obj, void * user_data);
40 static void update_resolution(lv_display_t * disp);
41 static void scr_load_internal(lv_obj_t * scr);
42 static void scr_load_anim_start(lv_anim_t * a);
43 static void opa_scale_anim(void * obj, int32_t v);
44 static void set_x_anim(void * obj, int32_t v);
45 static void set_y_anim(void * obj, int32_t v);
46 static void scr_anim_completed(lv_anim_t * a);
47 static bool is_out_anim(lv_screen_load_anim_t a);
48 static void disp_event_cb(lv_event_t * e);
49
50 /**********************
51 * STATIC VARIABLES
52 **********************/
53
54 /**********************
55 * MACROS
56 **********************/
57
58 /**********************
59 * GLOBAL FUNCTIONS
60 **********************/
61
lv_display_create(int32_t hor_res,int32_t ver_res)62 lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res)
63 {
64 lv_display_t * disp = lv_ll_ins_head(disp_ll_p);
65 LV_ASSERT_MALLOC(disp);
66 if(!disp) return NULL;
67
68 lv_memzero(disp, sizeof(lv_display_t));
69
70 disp->hor_res = hor_res;
71 disp->ver_res = ver_res;
72 disp->physical_hor_res = -1;
73 disp->physical_ver_res = -1;
74 disp->offset_x = 0;
75 disp->offset_y = 0;
76 disp->antialiasing = LV_COLOR_DEPTH > 8 ? 1 : 0;
77 disp->dpi = LV_DPI_DEF;
78 disp->color_format = LV_COLOR_FORMAT_NATIVE;
79
80
81 #if defined(LV_DRAW_SW_DRAW_UNIT_CNT) && (LV_DRAW_SW_DRAW_UNIT_CNT != 0)
82 disp->tile_cnt = LV_DRAW_SW_DRAW_UNIT_CNT;
83 #else
84 disp->tile_cnt = 1;
85 #endif
86
87 disp->layer_head = lv_malloc(sizeof(lv_layer_t));
88 LV_ASSERT_MALLOC(disp->layer_head);
89 if(disp->layer_head == NULL) return NULL;
90 lv_layer_init(disp->layer_head);
91
92 if(disp->layer_init) disp->layer_init(disp, disp->layer_head);
93 disp->layer_head->buf_area.x1 = 0;
94 disp->layer_head->buf_area.y1 = 0;
95 disp->layer_head->buf_area.x2 = hor_res - 1;
96 disp->layer_head->buf_area.y2 = ver_res - 1;
97 disp->layer_head->color_format = disp->color_format;
98
99 disp->inv_en_cnt = 1;
100 disp->last_activity_time = lv_tick_get();
101
102 lv_ll_init(&disp->sync_areas, sizeof(lv_area_t));
103
104 lv_display_t * disp_def_tmp = disp_def;
105 disp_def = disp; /*Temporarily change the default screen to create the default screens on the
106 new display*/
107 /*Create a refresh timer*/
108 disp->refr_timer = lv_timer_create(lv_display_refr_timer, LV_DEF_REFR_PERIOD, disp);
109 LV_ASSERT_MALLOC(disp->refr_timer);
110 if(disp->refr_timer == NULL) {
111 lv_free(disp);
112 return NULL;
113 }
114
115 #if LV_USE_THEME_DEFAULT
116 if(lv_theme_default_is_inited() == false) {
117 disp->theme = lv_theme_default_init(disp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED),
118 LV_THEME_DEFAULT_DARK, LV_FONT_DEFAULT);
119 }
120 else {
121 disp->theme = lv_theme_default_get();
122 }
123 #elif LV_USE_THEME_SIMPLE
124 if(lv_theme_simple_is_inited() == false) {
125 disp->theme = lv_theme_simple_init(disp);
126 }
127 else {
128 disp->theme = lv_theme_simple_get();
129 }
130 #endif
131
132 disp->bottom_layer = lv_obj_create(NULL); /*Create bottom layer on the display*/
133 disp->act_scr = lv_obj_create(NULL); /*Create a default screen on the display*/
134 disp->top_layer = lv_obj_create(NULL); /*Create top layer on the display*/
135 disp->sys_layer = lv_obj_create(NULL); /*Create sys layer on the display*/
136 lv_obj_remove_style_all(disp->bottom_layer);
137 lv_obj_remove_style_all(disp->top_layer);
138 lv_obj_remove_style_all(disp->sys_layer);
139 lv_obj_remove_flag(disp->top_layer, LV_OBJ_FLAG_CLICKABLE);
140 lv_obj_remove_flag(disp->sys_layer, LV_OBJ_FLAG_CLICKABLE);
141
142 lv_obj_set_scrollbar_mode(disp->bottom_layer, LV_SCROLLBAR_MODE_OFF);
143 lv_obj_set_scrollbar_mode(disp->top_layer, LV_SCROLLBAR_MODE_OFF);
144 lv_obj_set_scrollbar_mode(disp->sys_layer, LV_SCROLLBAR_MODE_OFF);
145
146 lv_obj_invalidate(disp->act_scr);
147
148 disp_def = disp_def_tmp; /*Revert the default display*/
149 if(disp_def == NULL) disp_def = disp; /*Initialize the default display*/
150
151 lv_display_add_event_cb(disp, disp_event_cb, LV_EVENT_REFR_REQUEST, NULL);
152
153 lv_timer_ready(disp->refr_timer); /*Be sure the screen will be refreshed immediately on start up*/
154
155 #if LV_USE_PERF_MONITOR
156 lv_sysmon_show_performance(disp);
157 #endif
158
159 #if LV_USE_MEM_MONITOR
160 lv_sysmon_show_memory(disp);
161 #endif
162
163 return disp;
164 }
165
lv_display_delete(lv_display_t * disp)166 void lv_display_delete(lv_display_t * disp)
167 {
168 bool was_default = false;
169 bool was_refr = false;
170 if(disp == lv_display_get_default()) was_default = true;
171 if(disp == lv_refr_get_disp_refreshing()) was_refr = true;
172
173 lv_display_send_event(disp, LV_EVENT_DELETE, NULL);
174 lv_event_remove_all(&(disp->event_list));
175
176 /*Detach the input devices*/
177 lv_indev_t * indev;
178 indev = lv_indev_get_next(NULL);
179 while(indev) {
180 if(lv_indev_get_display(indev) == disp) {
181 lv_indev_set_display(indev, NULL);
182 }
183 indev = lv_indev_get_next(indev);
184 }
185
186 /* Delete screen and other obj */
187 if(disp->sys_layer) {
188 lv_obj_delete(disp->sys_layer);
189 disp->sys_layer = NULL;
190 }
191 if(disp->top_layer) {
192 lv_obj_delete(disp->top_layer);
193 disp->top_layer = NULL;
194 }
195
196 if(disp->bottom_layer) {
197 lv_obj_delete(disp->bottom_layer);
198 disp->bottom_layer = NULL;
199 }
200
201 disp->act_scr = NULL;
202
203 while(disp->screen_cnt != 0) {
204 /*Delete the screens*/
205 lv_obj_delete(disp->screens[0]);
206 }
207
208 lv_ll_clear(&disp->sync_areas);
209 lv_ll_remove(disp_ll_p, disp);
210 if(disp->refr_timer) lv_timer_delete(disp->refr_timer);
211
212 if(disp->layer_deinit) disp->layer_deinit(disp, disp->layer_head);
213 lv_free(disp->layer_head);
214
215 lv_free(disp);
216
217 if(was_default) lv_display_set_default(lv_ll_get_head(disp_ll_p));
218
219 if(was_refr) lv_refr_set_disp_refreshing(NULL);
220 }
221
lv_display_set_default(lv_display_t * disp)222 void lv_display_set_default(lv_display_t * disp)
223 {
224 disp_def = disp;
225 }
226
lv_display_get_default(void)227 lv_display_t * lv_display_get_default(void)
228 {
229 return disp_def;
230 }
231
lv_display_get_next(lv_display_t * disp)232 lv_display_t * lv_display_get_next(lv_display_t * disp)
233 {
234 if(disp == NULL)
235 return lv_ll_get_head(disp_ll_p);
236 else
237 return lv_ll_get_next(disp_ll_p, disp);
238 }
239
240 /*---------------------
241 * RESOLUTION
242 *--------------------*/
243
lv_display_set_resolution(lv_display_t * disp,int32_t hor_res,int32_t ver_res)244 void lv_display_set_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res)
245 {
246 if(disp == NULL) disp = lv_display_get_default();
247 if(disp == NULL) return;
248
249 if(disp->hor_res == hor_res && disp->ver_res == ver_res) return;
250
251 disp->hor_res = hor_res;
252 disp->ver_res = ver_res;
253
254 update_resolution(disp);
255 }
256
lv_display_set_physical_resolution(lv_display_t * disp,int32_t hor_res,int32_t ver_res)257 void lv_display_set_physical_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res)
258 {
259 if(disp == NULL) disp = lv_display_get_default();
260 if(disp == NULL) return;
261
262 disp->physical_hor_res = hor_res;
263 disp->physical_ver_res = ver_res;
264
265 lv_obj_invalidate(disp->sys_layer);
266
267 }
268
lv_display_set_offset(lv_display_t * disp,int32_t x,int32_t y)269 void lv_display_set_offset(lv_display_t * disp, int32_t x, int32_t y)
270 {
271 if(disp == NULL) disp = lv_display_get_default();
272 if(disp == NULL) return;
273
274 disp->offset_x = x;
275 disp->offset_y = y;
276
277 lv_obj_invalidate(disp->sys_layer);
278
279 }
280
lv_display_set_dpi(lv_display_t * disp,int32_t dpi)281 void lv_display_set_dpi(lv_display_t * disp, int32_t dpi)
282 {
283 if(disp == NULL) disp = lv_display_get_default();
284 if(disp == NULL) return;
285
286 disp->dpi = dpi;
287 }
288
lv_display_get_horizontal_resolution(const lv_display_t * disp)289 int32_t lv_display_get_horizontal_resolution(const lv_display_t * disp)
290 {
291 if(disp == NULL) disp = lv_display_get_default();
292
293 if(disp == NULL) {
294 return 0;
295 }
296 else {
297 switch(disp->rotation) {
298 case LV_DISPLAY_ROTATION_90:
299 case LV_DISPLAY_ROTATION_270:
300 return disp->ver_res;
301 default:
302 return disp->hor_res;
303 }
304 }
305 }
306
lv_display_get_vertical_resolution(const lv_display_t * disp)307 int32_t lv_display_get_vertical_resolution(const lv_display_t * disp)
308 {
309 if(disp == NULL) disp = lv_display_get_default();
310
311 if(disp == NULL) {
312 return 0;
313 }
314 else {
315 switch(disp->rotation) {
316 case LV_DISPLAY_ROTATION_90:
317 case LV_DISPLAY_ROTATION_270:
318 return disp->hor_res;
319 default:
320 return disp->ver_res;
321 }
322 }
323 }
324
lv_display_get_physical_horizontal_resolution(const lv_display_t * disp)325 int32_t lv_display_get_physical_horizontal_resolution(const lv_display_t * disp)
326 {
327 if(disp == NULL) disp = lv_display_get_default();
328
329 if(disp == NULL) {
330 return 0;
331 }
332 else {
333 switch(disp->rotation) {
334 case LV_DISPLAY_ROTATION_90:
335 case LV_DISPLAY_ROTATION_270:
336 return disp->physical_ver_res > 0 ? disp->physical_ver_res : disp->ver_res;
337 default:
338 return disp->physical_hor_res > 0 ? disp->physical_hor_res : disp->hor_res;
339 }
340 }
341 }
342
lv_display_get_physical_vertical_resolution(const lv_display_t * disp)343 int32_t lv_display_get_physical_vertical_resolution(const lv_display_t * disp)
344 {
345 if(disp == NULL) disp = lv_display_get_default();
346
347 if(disp == NULL) {
348 return 0;
349 }
350 else {
351 switch(disp->rotation) {
352 case LV_DISPLAY_ROTATION_90:
353 case LV_DISPLAY_ROTATION_270:
354 return disp->physical_hor_res > 0 ? disp->physical_hor_res : disp->hor_res;
355 default:
356 return disp->physical_ver_res > 0 ? disp->physical_ver_res : disp->ver_res;
357 }
358 }
359 }
360
lv_display_get_offset_x(const lv_display_t * disp)361 int32_t lv_display_get_offset_x(const lv_display_t * disp)
362 {
363 if(disp == NULL) disp = lv_display_get_default();
364
365 if(disp == NULL) {
366 return 0;
367 }
368 else {
369 switch(disp->rotation) {
370 case LV_DISPLAY_ROTATION_90:
371 return disp->offset_y;
372 case LV_DISPLAY_ROTATION_180:
373 return lv_display_get_physical_horizontal_resolution(disp) - disp->offset_x;
374 case LV_DISPLAY_ROTATION_270:
375 return lv_display_get_physical_horizontal_resolution(disp) - disp->offset_y;
376 default:
377 return disp->offset_x;
378 }
379 }
380 }
381
lv_display_get_offset_y(const lv_display_t * disp)382 int32_t lv_display_get_offset_y(const lv_display_t * disp)
383 {
384 if(disp == NULL) disp = lv_display_get_default();
385
386 if(disp == NULL) {
387 return 0;
388 }
389 else {
390 switch(disp->rotation) {
391 case LV_DISPLAY_ROTATION_90:
392 return disp->offset_x;
393 case LV_DISPLAY_ROTATION_180:
394 return lv_display_get_physical_vertical_resolution(disp) - disp->offset_y;
395 case LV_DISPLAY_ROTATION_270:
396 return lv_display_get_physical_vertical_resolution(disp) - disp->offset_x;
397 default:
398 return disp->offset_y;
399 }
400 }
401 }
402
lv_display_get_dpi(const lv_display_t * disp)403 int32_t lv_display_get_dpi(const lv_display_t * disp)
404 {
405 if(disp == NULL) disp = lv_display_get_default();
406 if(disp == NULL) return LV_DPI_DEF; /*Do not return 0 because it might be a divider*/
407 return disp->dpi;
408 }
409
410 /*---------------------
411 * BUFFERING
412 *--------------------*/
413
lv_display_set_draw_buffers(lv_display_t * disp,lv_draw_buf_t * buf1,lv_draw_buf_t * buf2)414 void lv_display_set_draw_buffers(lv_display_t * disp, lv_draw_buf_t * buf1, lv_draw_buf_t * buf2)
415 {
416 if(disp == NULL) disp = lv_display_get_default();
417 if(disp == NULL) return;
418
419 disp->buf_1 = buf1;
420 disp->buf_2 = buf2;
421 disp->buf_act = disp->buf_1;
422 }
423
lv_display_set_buffers(lv_display_t * disp,void * buf1,void * buf2,uint32_t buf_size,lv_display_render_mode_t render_mode)424 void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size,
425 lv_display_render_mode_t render_mode)
426 {
427 LV_ASSERT_MSG(buf1 != NULL, "Null buffer");
428 lv_color_format_t cf = lv_display_get_color_format(disp);
429 uint32_t w = lv_display_get_horizontal_resolution(disp);
430 uint32_t h = lv_display_get_vertical_resolution(disp);
431
432 LV_ASSERT_MSG(w != 0 && h != 0, "display resolution is 0");
433
434 /* buf1 or buf2 is not aligned according to LV_DRAW_BUF_ALIGN */
435 LV_ASSERT_FORMAT_MSG(buf1 == lv_draw_buf_align(buf1, cf), "buf1 is not aligned: %p", buf1);
436 LV_ASSERT_FORMAT_MSG(buf2 == NULL || buf2 == lv_draw_buf_align(buf2, cf), "buf2 is not aligned: %p", buf2);
437
438 uint32_t stride = lv_draw_buf_width_to_stride(w, cf);
439 if(render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) {
440 /* for partial mode, we calculate the height based on the buf_size and stride */
441 h = buf_size / stride;
442 LV_ASSERT_MSG(h != 0, "the buffer is too small");
443 }
444 else {
445 LV_ASSERT_FORMAT_MSG(stride * h <= buf_size, "%s mode requires screen sized buffer(s)",
446 render_mode == LV_DISPLAY_RENDER_MODE_FULL ? "FULL" : "DIRECT");
447 }
448
449 lv_draw_buf_init(&disp->_static_buf1, w, h, cf, stride, buf1, buf_size);
450 lv_draw_buf_init(&disp->_static_buf2, w, h, cf, stride, buf2, buf_size);
451 lv_display_set_draw_buffers(disp, &disp->_static_buf1, buf2 ? &disp->_static_buf2 : NULL);
452 lv_display_set_render_mode(disp, render_mode);
453 }
454
lv_display_set_buffers_with_stride(lv_display_t * disp,void * buf1,void * buf2,uint32_t buf_size,uint32_t stride,lv_display_render_mode_t render_mode)455 void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size,
456 uint32_t stride, lv_display_render_mode_t render_mode)
457 {
458 LV_ASSERT_MSG(buf1 != NULL, "Null buffer");
459 lv_color_format_t cf = lv_display_get_color_format(disp);
460 uint32_t w = lv_display_get_horizontal_resolution(disp);
461 uint32_t h = lv_display_get_vertical_resolution(disp);
462 LV_ASSERT_MSG(w != 0 && h != 0, "display resolution is 0");
463
464 if(render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) {
465 /* for partial mode, we calculate the height based on the buf_size and stride */
466 h = buf_size / stride;
467 LV_ASSERT_MSG(h != 0, "the buffer is too small");
468 }
469 else {
470 LV_ASSERT_FORMAT_MSG(stride * h <= buf_size, "%s mode requires screen sized buffer(s)",
471 render_mode == LV_DISPLAY_RENDER_MODE_FULL ? "FULL" : "DIRECT");
472 }
473
474 lv_draw_buf_init(&disp->_static_buf1, w, h, cf, stride, buf1, buf_size);
475 lv_draw_buf_init(&disp->_static_buf2, w, h, cf, stride, buf2, buf_size);
476 lv_display_set_draw_buffers(disp, &disp->_static_buf1, buf2 ? &disp->_static_buf2 : NULL);
477 lv_display_set_render_mode(disp, render_mode);
478 }
479
lv_display_set_render_mode(lv_display_t * disp,lv_display_render_mode_t render_mode)480 void lv_display_set_render_mode(lv_display_t * disp, lv_display_render_mode_t render_mode)
481 {
482 if(disp == NULL) disp = lv_display_get_default();
483 if(disp == NULL) return;
484 disp->render_mode = render_mode;
485 }
486
lv_display_set_flush_cb(lv_display_t * disp,lv_display_flush_cb_t flush_cb)487 void lv_display_set_flush_cb(lv_display_t * disp, lv_display_flush_cb_t flush_cb)
488 {
489 if(disp == NULL) disp = lv_display_get_default();
490 if(disp == NULL) return;
491
492 disp->flush_cb = flush_cb;
493 }
494
lv_display_set_flush_wait_cb(lv_display_t * disp,lv_display_flush_wait_cb_t wait_cb)495 void lv_display_set_flush_wait_cb(lv_display_t * disp, lv_display_flush_wait_cb_t wait_cb)
496 {
497 if(disp == NULL) disp = lv_display_get_default();
498 if(disp == NULL) return;
499
500 disp->flush_wait_cb = wait_cb;
501 }
502
lv_display_set_color_format(lv_display_t * disp,lv_color_format_t color_format)503 void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_format)
504 {
505 if(disp == NULL) disp = lv_display_get_default();
506 if(disp == NULL) return;
507
508 disp->color_format = color_format;
509 disp->layer_head->color_format = color_format;
510 if(disp->buf_1) disp->buf_1->header.cf = color_format;
511 if(disp->buf_2) disp->buf_2->header.cf = color_format;
512
513 lv_display_send_event(disp, LV_EVENT_COLOR_FORMAT_CHANGED, NULL);
514 }
515
lv_display_get_color_format(lv_display_t * disp)516 lv_color_format_t lv_display_get_color_format(lv_display_t * disp)
517 {
518 if(disp == NULL) disp = lv_display_get_default();
519 if(disp == NULL) return LV_COLOR_FORMAT_UNKNOWN;
520
521 return disp->color_format;
522 }
523
lv_display_set_tile_cnt(lv_display_t * disp,uint32_t tile_cnt)524 void lv_display_set_tile_cnt(lv_display_t * disp, uint32_t tile_cnt)
525 {
526 LV_ASSERT_FORMAT_MSG(tile_cnt < 256, "tile_cnt must be smaller than 256 (%" LV_PRId32 " was used)", tile_cnt);
527
528 if(disp == NULL) disp = lv_display_get_default();
529 if(disp == NULL) return;
530
531 disp->tile_cnt = tile_cnt;
532 }
533
lv_display_get_tile_cnt(lv_display_t * disp)534 uint32_t lv_display_get_tile_cnt(lv_display_t * disp)
535 {
536 if(disp == NULL) disp = lv_display_get_default();
537 if(disp == NULL) return 0;
538
539 return disp->tile_cnt;
540 }
541
lv_display_set_antialiasing(lv_display_t * disp,bool en)542 void lv_display_set_antialiasing(lv_display_t * disp, bool en)
543 {
544 if(disp == NULL) disp = lv_display_get_default();
545 if(disp == NULL) return;
546
547 disp->antialiasing = en;
548 }
549
lv_display_get_antialiasing(lv_display_t * disp)550 bool lv_display_get_antialiasing(lv_display_t * disp)
551 {
552 if(disp == NULL) disp = lv_display_get_default();
553 if(disp == NULL) return false;
554
555 return disp->antialiasing;
556 }
557
lv_display_flush_ready(lv_display_t * disp)558 LV_ATTRIBUTE_FLUSH_READY void lv_display_flush_ready(lv_display_t * disp)
559 {
560 disp->flushing = 0;
561 }
562
lv_display_flush_is_last(lv_display_t * disp)563 LV_ATTRIBUTE_FLUSH_READY bool lv_display_flush_is_last(lv_display_t * disp)
564 {
565 return disp->flushing_last;
566 }
567
lv_display_is_double_buffered(lv_display_t * disp)568 bool lv_display_is_double_buffered(lv_display_t * disp)
569 {
570 return disp->buf_2 != NULL;
571 }
572
573 /*---------------------
574 * SCREENS
575 *--------------------*/
576
lv_display_get_screen_active(lv_display_t * disp)577 lv_obj_t * lv_display_get_screen_active(lv_display_t * disp)
578 {
579 if(!disp) disp = lv_display_get_default();
580 if(!disp) {
581 LV_LOG_WARN("no display registered to get its active screen");
582 return NULL;
583 }
584
585 return disp->act_scr;
586 }
587
lv_display_get_screen_prev(lv_display_t * disp)588 lv_obj_t * lv_display_get_screen_prev(lv_display_t * disp)
589 {
590 if(!disp) disp = lv_display_get_default();
591 if(!disp) {
592 LV_LOG_WARN("no display registered to get its previous screen");
593 return NULL;
594 }
595
596 return disp->prev_scr;
597 }
598
lv_display_get_layer_top(lv_display_t * disp)599 lv_obj_t * lv_display_get_layer_top(lv_display_t * disp)
600 {
601 if(!disp) disp = lv_display_get_default();
602 if(!disp) {
603 LV_LOG_WARN("lv_layer_top: no display registered to get its top layer");
604 return NULL;
605 }
606
607 return disp->top_layer;
608 }
609
lv_display_get_layer_sys(lv_display_t * disp)610 lv_obj_t * lv_display_get_layer_sys(lv_display_t * disp)
611 {
612 if(!disp) disp = lv_display_get_default();
613 if(!disp) {
614 LV_LOG_WARN("lv_layer_sys: no display registered to get its sys. layer");
615 return NULL;
616 }
617
618 return disp->sys_layer;
619 }
620
lv_display_get_layer_bottom(lv_display_t * disp)621 lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp)
622 {
623 if(!disp) disp = lv_display_get_default();
624 if(!disp) {
625 LV_LOG_WARN("lv_layer_bottom: no display registered to get its bottom layer");
626 return NULL;
627 }
628
629 return disp->bottom_layer;
630 }
631
lv_screen_load(struct _lv_obj_t * scr)632 void lv_screen_load(struct _lv_obj_t * scr)
633 {
634 lv_screen_load_anim(scr, LV_SCR_LOAD_ANIM_NONE, 0, 0, false);
635 }
636
lv_screen_load_anim(lv_obj_t * new_scr,lv_screen_load_anim_t anim_type,uint32_t time,uint32_t delay,bool auto_del)637 void lv_screen_load_anim(lv_obj_t * new_scr, lv_screen_load_anim_t anim_type, uint32_t time, uint32_t delay,
638 bool auto_del)
639 {
640 lv_display_t * d = lv_obj_get_display(new_scr);
641 lv_obj_t * act_scr = d->act_scr;
642
643 if(act_scr == new_scr || d->scr_to_load == new_scr) {
644 return;
645 }
646
647 /*If another screen load animation is in progress
648 *make target screen loaded immediately. */
649 if(d->scr_to_load && act_scr != d->scr_to_load) {
650 lv_anim_delete(d->scr_to_load, NULL);
651 lv_obj_set_pos(d->scr_to_load, 0, 0);
652 lv_obj_remove_local_style_prop(d->scr_to_load, LV_STYLE_OPA, 0);
653
654 d->prev_scr = d->act_scr;
655 act_scr = d->scr_to_load; /*Active screen changed.*/
656
657 scr_load_internal(d->scr_to_load);
658 }
659
660 d->scr_to_load = new_scr;
661
662 if(d->prev_scr && d->del_prev) lv_obj_delete(d->prev_scr);
663 d->prev_scr = NULL;
664
665 d->draw_prev_over_act = is_out_anim(anim_type);
666 d->del_prev = auto_del;
667
668 /*Be sure there is no other animation on the screens*/
669 lv_anim_delete(new_scr, NULL);
670 if(act_scr) lv_anim_delete(act_scr, NULL);
671
672 /*Be sure both screens are in a normal position*/
673 lv_obj_set_pos(new_scr, 0, 0);
674 if(act_scr) lv_obj_set_pos(act_scr, 0, 0);
675 lv_obj_remove_local_style_prop(new_scr, LV_STYLE_OPA, 0);
676 if(act_scr) lv_obj_remove_local_style_prop(act_scr, LV_STYLE_OPA, 0);
677
678 /*Shortcut for immediate load*/
679 if(time == 0 && delay == 0) {
680 scr_load_internal(new_scr);
681 if(auto_del && act_scr) lv_obj_delete(act_scr);
682 return;
683 }
684
685 lv_anim_t a_new;
686 lv_anim_init(&a_new);
687 lv_anim_set_var(&a_new, new_scr);
688 lv_anim_set_start_cb(&a_new, scr_load_anim_start);
689 lv_anim_set_completed_cb(&a_new, scr_anim_completed);
690 lv_anim_set_duration(&a_new, time);
691 lv_anim_set_delay(&a_new, delay);
692
693 lv_anim_t a_old;
694 lv_anim_init(&a_old);
695 lv_anim_set_var(&a_old, act_scr);
696 lv_anim_set_duration(&a_old, time);
697 lv_anim_set_delay(&a_old, delay);
698
699 switch(anim_type) {
700 case LV_SCR_LOAD_ANIM_NONE:
701 /*Create a dummy animation to apply the delay*/
702 lv_anim_set_exec_cb(&a_new, set_x_anim);
703 lv_anim_set_values(&a_new, 0, 0);
704 break;
705 case LV_SCR_LOAD_ANIM_OVER_LEFT:
706 lv_anim_set_exec_cb(&a_new, set_x_anim);
707 lv_anim_set_values(&a_new, lv_display_get_horizontal_resolution(d), 0);
708 break;
709 case LV_SCR_LOAD_ANIM_OVER_RIGHT:
710 lv_anim_set_exec_cb(&a_new, set_x_anim);
711 lv_anim_set_values(&a_new, -lv_display_get_horizontal_resolution(d), 0);
712 break;
713 case LV_SCR_LOAD_ANIM_OVER_TOP:
714 lv_anim_set_exec_cb(&a_new, set_y_anim);
715 lv_anim_set_values(&a_new, lv_display_get_vertical_resolution(d), 0);
716 break;
717 case LV_SCR_LOAD_ANIM_OVER_BOTTOM:
718 lv_anim_set_exec_cb(&a_new, set_y_anim);
719 lv_anim_set_values(&a_new, -lv_display_get_vertical_resolution(d), 0);
720 break;
721 case LV_SCR_LOAD_ANIM_MOVE_LEFT:
722 lv_anim_set_exec_cb(&a_new, set_x_anim);
723 lv_anim_set_values(&a_new, lv_display_get_horizontal_resolution(d), 0);
724
725 lv_anim_set_exec_cb(&a_old, set_x_anim);
726 lv_anim_set_values(&a_old, 0, -lv_display_get_horizontal_resolution(d));
727 break;
728 case LV_SCR_LOAD_ANIM_MOVE_RIGHT:
729 lv_anim_set_exec_cb(&a_new, set_x_anim);
730 lv_anim_set_values(&a_new, -lv_display_get_horizontal_resolution(d), 0);
731
732 lv_anim_set_exec_cb(&a_old, set_x_anim);
733 lv_anim_set_values(&a_old, 0, lv_display_get_horizontal_resolution(d));
734 break;
735 case LV_SCR_LOAD_ANIM_MOVE_TOP:
736 lv_anim_set_exec_cb(&a_new, set_y_anim);
737 lv_anim_set_values(&a_new, lv_display_get_vertical_resolution(d), 0);
738
739 lv_anim_set_exec_cb(&a_old, set_y_anim);
740 lv_anim_set_values(&a_old, 0, -lv_display_get_vertical_resolution(d));
741 break;
742 case LV_SCR_LOAD_ANIM_MOVE_BOTTOM:
743 lv_anim_set_exec_cb(&a_new, set_y_anim);
744 lv_anim_set_values(&a_new, -lv_display_get_vertical_resolution(d), 0);
745
746 lv_anim_set_exec_cb(&a_old, set_y_anim);
747 lv_anim_set_values(&a_old, 0, lv_display_get_vertical_resolution(d));
748 break;
749 case LV_SCR_LOAD_ANIM_FADE_IN:
750 lv_anim_set_exec_cb(&a_new, opa_scale_anim);
751 lv_anim_set_values(&a_new, LV_OPA_TRANSP, LV_OPA_COVER);
752 break;
753 case LV_SCR_LOAD_ANIM_FADE_OUT:
754 lv_anim_set_exec_cb(&a_old, opa_scale_anim);
755 lv_anim_set_values(&a_old, LV_OPA_COVER, LV_OPA_TRANSP);
756 break;
757 case LV_SCR_LOAD_ANIM_OUT_LEFT:
758 lv_anim_set_exec_cb(&a_old, set_x_anim);
759 lv_anim_set_values(&a_old, 0, -lv_display_get_horizontal_resolution(d));
760 break;
761 case LV_SCR_LOAD_ANIM_OUT_RIGHT:
762 lv_anim_set_exec_cb(&a_old, set_x_anim);
763 lv_anim_set_values(&a_old, 0, lv_display_get_horizontal_resolution(d));
764 break;
765 case LV_SCR_LOAD_ANIM_OUT_TOP:
766 lv_anim_set_exec_cb(&a_old, set_y_anim);
767 lv_anim_set_values(&a_old, 0, -lv_display_get_vertical_resolution(d));
768 break;
769 case LV_SCR_LOAD_ANIM_OUT_BOTTOM:
770 lv_anim_set_exec_cb(&a_old, set_y_anim);
771 lv_anim_set_values(&a_old, 0, lv_display_get_vertical_resolution(d));
772 break;
773 }
774
775 if(act_scr) lv_obj_send_event(act_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL);
776
777 lv_anim_start(&a_new);
778 if(act_scr) lv_anim_start(&a_old);
779 }
780
781 /*---------------------
782 * OTHERS
783 *--------------------*/
784
lv_display_add_event_cb(lv_display_t * disp,lv_event_cb_t event_cb,lv_event_code_t filter,void * user_data)785 void lv_display_add_event_cb(lv_display_t * disp, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data)
786 {
787 LV_ASSERT_NULL(disp);
788
789 lv_event_add(&disp->event_list, event_cb, filter, user_data);
790 }
791
lv_display_get_event_count(lv_display_t * disp)792 uint32_t lv_display_get_event_count(lv_display_t * disp)
793 {
794 LV_ASSERT_NULL(disp);
795 return lv_event_get_count(&disp->event_list);
796 }
797
lv_display_get_event_dsc(lv_display_t * disp,uint32_t index)798 lv_event_dsc_t * lv_display_get_event_dsc(lv_display_t * disp, uint32_t index)
799 {
800 LV_ASSERT_NULL(disp);
801 return lv_event_get_dsc(&disp->event_list, index);
802
803 }
804
lv_display_delete_event(lv_display_t * disp,uint32_t index)805 bool lv_display_delete_event(lv_display_t * disp, uint32_t index)
806 {
807 LV_ASSERT_NULL(disp);
808
809 return lv_event_remove(&disp->event_list, index);
810 }
811
lv_display_remove_event_cb_with_user_data(lv_display_t * disp,lv_event_cb_t event_cb,void * user_data)812 uint32_t lv_display_remove_event_cb_with_user_data(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data)
813 {
814 LV_ASSERT_NULL(disp);
815
816 uint32_t event_cnt = lv_display_get_event_count(disp);
817 uint32_t removed_count = 0;
818 int32_t i;
819
820 for(i = event_cnt - 1; i >= 0; i--) {
821 lv_event_dsc_t * dsc = lv_display_get_event_dsc(disp, i);
822 if(dsc && dsc->cb == event_cb && dsc->user_data == user_data) {
823 lv_display_delete_event(disp, i);
824 removed_count ++;
825 }
826 }
827
828 return removed_count;
829 }
830
lv_display_send_event(lv_display_t * disp,lv_event_code_t code,void * param)831 lv_result_t lv_display_send_event(lv_display_t * disp, lv_event_code_t code, void * param)
832 {
833
834 lv_event_t e;
835 lv_memzero(&e, sizeof(e));
836 e.code = code;
837 e.current_target = disp;
838 e.original_target = disp;
839 e.param = param;
840 lv_result_t res;
841 res = lv_event_send(&disp->event_list, &e, true);
842 if(res != LV_RESULT_OK) return res;
843
844 res = lv_event_send(&disp->event_list, &e, false);
845 if(res != LV_RESULT_OK) return res;
846
847 return res;
848 }
849
lv_event_get_invalidated_area(lv_event_t * e)850 lv_area_t * lv_event_get_invalidated_area(lv_event_t * e)
851 {
852 if(e->code == LV_EVENT_INVALIDATE_AREA) {
853 return lv_event_get_param(e);
854 }
855 else {
856 LV_LOG_WARN("Not interpreted with this event code");
857 return NULL;
858 }
859 }
860
lv_display_set_rotation(lv_display_t * disp,lv_display_rotation_t rotation)861 void lv_display_set_rotation(lv_display_t * disp, lv_display_rotation_t rotation)
862 {
863 if(disp == NULL) disp = lv_display_get_default();
864 if(disp == NULL) return;
865
866 disp->rotation = rotation;
867 update_resolution(disp);
868 }
869
lv_display_get_rotation(lv_display_t * disp)870 lv_display_rotation_t lv_display_get_rotation(lv_display_t * disp)
871 {
872 if(disp == NULL) disp = lv_display_get_default();
873 if(disp == NULL) return LV_DISPLAY_ROTATION_0;
874 return disp->rotation;
875 }
876
lv_display_set_theme(lv_display_t * disp,lv_theme_t * th)877 void lv_display_set_theme(lv_display_t * disp, lv_theme_t * th)
878 {
879 if(!disp) disp = lv_display_get_default();
880 if(!disp) {
881 LV_LOG_WARN("no display registered");
882 return;
883 }
884
885 disp->theme = th;
886
887 if(disp->screen_cnt == 4 &&
888 lv_obj_get_child_count(disp->screens[0]) == 0 &&
889 lv_obj_get_child_count(disp->screens[1]) == 0 &&
890 lv_obj_get_child_count(disp->screens[2]) == 0) {
891 lv_theme_apply(disp->screens[0]);
892 }
893 }
894
lv_display_get_theme(lv_display_t * disp)895 lv_theme_t * lv_display_get_theme(lv_display_t * disp)
896 {
897 if(disp == NULL) disp = lv_display_get_default();
898 return disp->theme;
899 }
900
lv_display_get_inactive_time(const lv_display_t * disp)901 uint32_t lv_display_get_inactive_time(const lv_display_t * disp)
902 {
903 if(disp) return lv_tick_elaps(disp->last_activity_time);
904
905 lv_display_t * d;
906 uint32_t t = UINT32_MAX;
907 d = lv_display_get_next(NULL);
908 while(d) {
909 uint32_t elaps = lv_tick_elaps(d->last_activity_time);
910 t = LV_MIN(t, elaps);
911 d = lv_display_get_next(d);
912 }
913
914 return t;
915 }
916
lv_display_trigger_activity(lv_display_t * disp)917 void lv_display_trigger_activity(lv_display_t * disp)
918 {
919 if(!disp) disp = lv_display_get_default();
920 if(!disp) {
921 LV_LOG_WARN("lv_display_trigger_activity: no display registered");
922 return;
923 }
924
925 disp->last_activity_time = lv_tick_get();
926 }
927
lv_display_enable_invalidation(lv_display_t * disp,bool en)928 void lv_display_enable_invalidation(lv_display_t * disp, bool en)
929 {
930 if(!disp) disp = lv_display_get_default();
931 if(!disp) {
932 LV_LOG_WARN("no display registered");
933 return;
934 }
935
936 disp->inv_en_cnt += en ? 1 : -1;
937 }
938
lv_display_is_invalidation_enabled(lv_display_t * disp)939 bool lv_display_is_invalidation_enabled(lv_display_t * disp)
940 {
941 if(!disp) disp = lv_display_get_default();
942 if(!disp) {
943 LV_LOG_WARN("no display registered");
944 return false;
945 }
946
947 return (disp->inv_en_cnt > 0);
948 }
949
lv_display_get_refr_timer(lv_display_t * disp)950 lv_timer_t * lv_display_get_refr_timer(lv_display_t * disp)
951 {
952 if(!disp) disp = lv_display_get_default();
953 if(!disp) return NULL;
954
955 return disp->refr_timer;
956 }
957
lv_display_delete_refr_timer(lv_display_t * disp)958 void lv_display_delete_refr_timer(lv_display_t * disp)
959 {
960 if(!disp) disp = lv_display_get_default();
961 if(!disp || !disp->refr_timer) return;
962
963 lv_timer_delete(disp->refr_timer);
964 disp->refr_timer = NULL;
965 }
966
lv_display_set_user_data(lv_display_t * disp,void * user_data)967 void lv_display_set_user_data(lv_display_t * disp, void * user_data)
968 {
969 if(!disp) disp = lv_display_get_default();
970 if(!disp) return;
971 disp->user_data = user_data;
972 }
973
lv_display_set_driver_data(lv_display_t * disp,void * driver_data)974 void lv_display_set_driver_data(lv_display_t * disp, void * driver_data)
975 {
976 if(!disp) disp = lv_display_get_default();
977 if(!disp) return;
978
979 disp->driver_data = driver_data;
980 }
981
lv_display_get_user_data(lv_display_t * disp)982 void * lv_display_get_user_data(lv_display_t * disp)
983 {
984 if(!disp) disp = lv_display_get_default();
985 if(!disp) return NULL;
986 return disp->user_data;
987 }
988
lv_display_get_driver_data(lv_display_t * disp)989 void * lv_display_get_driver_data(lv_display_t * disp)
990 {
991 if(!disp) disp = lv_display_get_default();
992 if(!disp) return NULL;
993
994 return disp->driver_data;
995 }
996
lv_display_get_buf_active(lv_display_t * disp)997 lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp)
998 {
999 if(!disp) disp = lv_display_get_default();
1000 if(!disp) return NULL;
1001 return disp->buf_act;
1002 }
1003
lv_display_rotate_area(lv_display_t * disp,lv_area_t * area)1004 void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area)
1005 {
1006 lv_display_rotation_t rotation = lv_display_get_rotation(disp);
1007
1008 int32_t w = lv_area_get_width(area);
1009 int32_t h = lv_area_get_height(area);
1010
1011 switch(rotation) {
1012 case LV_DISPLAY_ROTATION_0:
1013 return;
1014 case LV_DISPLAY_ROTATION_90:
1015 area->y2 = disp->ver_res - area->x1 - 1;
1016 area->x1 = area->y1;
1017 area->x2 = area->x1 + h - 1;
1018 area->y1 = area->y2 - w + 1;
1019 break;
1020 case LV_DISPLAY_ROTATION_180:
1021 area->y2 = disp->ver_res - area->y1 - 1;
1022 area->y1 = area->y2 - h + 1;
1023 area->x2 = disp->hor_res - area->x1 - 1;
1024 area->x1 = area->x2 - w + 1;
1025 break;
1026 case LV_DISPLAY_ROTATION_270:
1027 area->x1 = disp->hor_res - area->y2 - 1;
1028 area->y2 = area->x2;
1029 area->x2 = area->x1 + h - 1;
1030 area->y1 = area->y2 - w + 1;
1031 break;
1032 }
1033 }
1034
lv_display_get_draw_buf_size(lv_display_t * disp)1035 uint32_t lv_display_get_draw_buf_size(lv_display_t * disp)
1036 {
1037 if(!disp) disp = lv_display_get_default();
1038 if(!disp) return 0;
1039
1040 if(disp->buf_1) {
1041 return disp->buf_1->data_size;
1042 }
1043 return 0;
1044 }
1045
lv_display_get_invalidated_draw_buf_size(lv_display_t * disp,uint32_t width,uint32_t height)1046 uint32_t lv_display_get_invalidated_draw_buf_size(lv_display_t * disp, uint32_t width, uint32_t height)
1047 {
1048 if(!disp) disp = lv_display_get_default();
1049 if(!disp) return 0;
1050
1051 if(disp->render_mode == LV_DISPLAY_RENDER_MODE_FULL) {
1052 width = lv_display_get_horizontal_resolution(disp);
1053 height = lv_display_get_vertical_resolution(disp);
1054 }
1055
1056 lv_color_format_t cf = lv_display_get_color_format(disp);
1057 uint32_t stride = lv_draw_buf_width_to_stride(width, cf);
1058 uint32_t buf_size = stride * height;
1059
1060 LV_ASSERT(disp->buf_1 && disp->buf_1->data_size >= buf_size);
1061 if(disp->buf_2) LV_ASSERT(disp->buf_2->data_size >= buf_size);
1062
1063 return buf_size;
1064 }
1065
lv_screen_active(void)1066 lv_obj_t * lv_screen_active(void)
1067 {
1068 return lv_display_get_screen_active(lv_display_get_default());
1069 }
1070
lv_layer_top(void)1071 lv_obj_t * lv_layer_top(void)
1072 {
1073 return lv_display_get_layer_top(lv_display_get_default());
1074 }
1075
lv_layer_sys(void)1076 lv_obj_t * lv_layer_sys(void)
1077 {
1078 return lv_display_get_layer_sys(lv_display_get_default());
1079 }
1080
lv_layer_bottom(void)1081 lv_obj_t * lv_layer_bottom(void)
1082 {
1083 return lv_display_get_layer_bottom(lv_display_get_default());
1084 }
1085
lv_dpx(int32_t n)1086 int32_t lv_dpx(int32_t n)
1087 {
1088 return LV_DPX(n);
1089 }
1090
lv_display_dpx(const lv_display_t * disp,int32_t n)1091 int32_t lv_display_dpx(const lv_display_t * disp, int32_t n)
1092 {
1093 return LV_DPX_CALC(lv_display_get_dpi(disp), n);
1094 }
1095
1096 /**********************
1097 * STATIC FUNCTIONS
1098 **********************/
1099
update_resolution(lv_display_t * disp)1100 static void update_resolution(lv_display_t * disp)
1101 {
1102 int32_t hor_res = lv_display_get_horizontal_resolution(disp);
1103 int32_t ver_res = lv_display_get_vertical_resolution(disp);
1104
1105 lv_area_t prev_coords;
1106 lv_obj_get_coords(disp->sys_layer, &prev_coords);
1107 uint32_t i;
1108 for(i = 0; i < disp->screen_cnt; i++) {
1109 lv_area_set_width(&disp->screens[i]->coords, hor_res);
1110 lv_area_set_height(&disp->screens[i]->coords, ver_res);
1111 lv_obj_send_event(disp->screens[i], LV_EVENT_SIZE_CHANGED, &prev_coords);
1112 }
1113
1114 lv_area_set_width(&disp->top_layer->coords, hor_res);
1115 lv_area_set_height(&disp->top_layer->coords, ver_res);
1116 lv_obj_send_event(disp->top_layer, LV_EVENT_SIZE_CHANGED, &prev_coords);
1117
1118 lv_area_set_width(&disp->sys_layer->coords, hor_res);
1119 lv_area_set_height(&disp->sys_layer->coords, ver_res);
1120 lv_obj_send_event(disp->sys_layer, LV_EVENT_SIZE_CHANGED, &prev_coords);
1121
1122 lv_area_set_width(&disp->bottom_layer->coords, hor_res);
1123 lv_area_set_height(&disp->bottom_layer->coords, ver_res);
1124 lv_obj_send_event(disp->bottom_layer, LV_EVENT_SIZE_CHANGED, &prev_coords);
1125
1126 lv_memzero(disp->inv_areas, sizeof(disp->inv_areas));
1127 lv_memzero(disp->inv_area_joined, sizeof(disp->inv_area_joined));
1128 disp->inv_p = 0;
1129 lv_obj_invalidate(disp->sys_layer);
1130
1131 lv_obj_tree_walk(NULL, invalidate_layout_cb, NULL);
1132
1133 lv_display_send_event(disp, LV_EVENT_RESOLUTION_CHANGED, NULL);
1134 }
1135
invalidate_layout_cb(lv_obj_t * obj,void * user_data)1136 static lv_obj_tree_walk_res_t invalidate_layout_cb(lv_obj_t * obj, void * user_data)
1137 {
1138 LV_UNUSED(user_data);
1139 lv_obj_mark_layout_as_dirty(obj);
1140 return LV_OBJ_TREE_WALK_NEXT;
1141 }
1142
scr_load_internal(lv_obj_t * scr)1143 static void scr_load_internal(lv_obj_t * scr)
1144 {
1145 /*scr must not be NULL, but d->act_scr might be*/
1146 LV_ASSERT_NULL(scr);
1147 if(scr == NULL) return;
1148
1149 lv_display_t * d = lv_obj_get_display(scr);
1150 if(!d) return; /*Shouldn't happen, just to be sure*/
1151
1152 lv_obj_t * old_scr = d->act_scr;
1153
1154 if(old_scr) lv_obj_send_event(old_scr, LV_EVENT_SCREEN_UNLOAD_START, NULL);
1155 lv_obj_send_event(scr, LV_EVENT_SCREEN_LOAD_START, NULL);
1156
1157 d->act_scr = scr;
1158 d->scr_to_load = NULL;
1159
1160 lv_obj_send_event(scr, LV_EVENT_SCREEN_LOADED, NULL);
1161 if(old_scr) lv_obj_send_event(old_scr, LV_EVENT_SCREEN_UNLOADED, NULL);
1162
1163 lv_obj_invalidate(scr);
1164 }
1165
scr_load_anim_start(lv_anim_t * a)1166 static void scr_load_anim_start(lv_anim_t * a)
1167 {
1168 lv_display_t * d = lv_obj_get_display(a->var);
1169
1170 d->prev_scr = d->act_scr;
1171 d->act_scr = a->var;
1172
1173 lv_obj_send_event(d->act_scr, LV_EVENT_SCREEN_LOAD_START, NULL);
1174 }
1175
opa_scale_anim(void * obj,int32_t v)1176 static void opa_scale_anim(void * obj, int32_t v)
1177 {
1178 lv_obj_set_style_opa(obj, v, 0);
1179 }
1180
set_x_anim(void * obj,int32_t v)1181 static void set_x_anim(void * obj, int32_t v)
1182 {
1183 lv_obj_set_x(obj, v);
1184 }
1185
set_y_anim(void * obj,int32_t v)1186 static void set_y_anim(void * obj, int32_t v)
1187 {
1188 lv_obj_set_y(obj, v);
1189 }
1190
scr_anim_completed(lv_anim_t * a)1191 static void scr_anim_completed(lv_anim_t * a)
1192 {
1193 lv_display_t * d = lv_obj_get_display(a->var);
1194
1195 lv_obj_send_event(d->act_scr, LV_EVENT_SCREEN_LOADED, NULL);
1196 lv_obj_send_event(d->prev_scr, LV_EVENT_SCREEN_UNLOADED, NULL);
1197
1198 if(d->prev_scr && d->del_prev) lv_obj_delete(d->prev_scr);
1199 d->prev_scr = NULL;
1200 d->draw_prev_over_act = false;
1201 d->scr_to_load = NULL;
1202 lv_obj_remove_local_style_prop(a->var, LV_STYLE_OPA, 0);
1203 lv_obj_invalidate(d->act_scr);
1204 }
1205
is_out_anim(lv_screen_load_anim_t anim_type)1206 static bool is_out_anim(lv_screen_load_anim_t anim_type)
1207 {
1208 return anim_type == LV_SCR_LOAD_ANIM_FADE_OUT ||
1209 anim_type == LV_SCR_LOAD_ANIM_OUT_LEFT ||
1210 anim_type == LV_SCR_LOAD_ANIM_OUT_RIGHT ||
1211 anim_type == LV_SCR_LOAD_ANIM_OUT_TOP ||
1212 anim_type == LV_SCR_LOAD_ANIM_OUT_BOTTOM;
1213 }
1214
disp_event_cb(lv_event_t * e)1215 static void disp_event_cb(lv_event_t * e)
1216 {
1217 lv_event_code_t code = lv_event_get_code(e);
1218 lv_display_t * disp = lv_event_get_target(e);
1219 switch(code) {
1220 case LV_EVENT_REFR_REQUEST:
1221 if(disp->refr_timer) lv_timer_resume(disp->refr_timer);
1222 break;
1223
1224 default:
1225 break;
1226 }
1227 }
1228