1 /**
2  * @file lv_display.h
3  *
4  */
5 
6 #ifndef LV_DISPLAY_H
7 #define LV_DISPLAY_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../misc/lv_types.h"
17 #include "../misc/lv_timer.h"
18 #include "../misc/lv_event.h"
19 #include "../misc/lv_color.h"
20 #include "../misc/lv_area.h"
21 
22 /*********************
23  *      DEFINES
24  *********************/
25 
26 #ifndef LV_ATTRIBUTE_FLUSH_READY
27 #define LV_ATTRIBUTE_FLUSH_READY
28 #endif
29 
30 /**********************
31  *      TYPEDEFS
32  **********************/
33 
34 typedef enum {
35     LV_DISPLAY_ROTATION_0 = 0,
36     LV_DISPLAY_ROTATION_90,
37     LV_DISPLAY_ROTATION_180,
38     LV_DISPLAY_ROTATION_270
39 } lv_display_rotation_t;
40 
41 typedef enum {
42     /**
43      * Use the buffer(s) to render the screen is smaller parts.
44      * This way the buffers can be smaller then the display to save RAM. At least 1/10 screen size buffer(s) are recommended.
45      */
46     LV_DISPLAY_RENDER_MODE_PARTIAL,
47 
48     /**
49      * The buffer(s) has to be screen sized and LVGL will render into the correct location of the buffer.
50      * This way the buffer always contain the whole image. Only the changed ares will be updated.
51      * With 2 buffers the buffers' content are kept in sync automatically and in flush_cb only address change is required.
52      */
53     LV_DISPLAY_RENDER_MODE_DIRECT,
54 
55     /**
56      * Always redraw the whole screen even if only one pixel has been changed.
57      * With 2 buffers in flush_cb only an address change is required.
58      */
59     LV_DISPLAY_RENDER_MODE_FULL,
60 } lv_display_render_mode_t;
61 
62 typedef enum {
63     LV_SCR_LOAD_ANIM_NONE,
64     LV_SCR_LOAD_ANIM_OVER_LEFT,
65     LV_SCR_LOAD_ANIM_OVER_RIGHT,
66     LV_SCR_LOAD_ANIM_OVER_TOP,
67     LV_SCR_LOAD_ANIM_OVER_BOTTOM,
68     LV_SCR_LOAD_ANIM_MOVE_LEFT,
69     LV_SCR_LOAD_ANIM_MOVE_RIGHT,
70     LV_SCR_LOAD_ANIM_MOVE_TOP,
71     LV_SCR_LOAD_ANIM_MOVE_BOTTOM,
72     LV_SCR_LOAD_ANIM_FADE_IN,
73     LV_SCR_LOAD_ANIM_FADE_ON = LV_SCR_LOAD_ANIM_FADE_IN, /*For backward compatibility*/
74     LV_SCR_LOAD_ANIM_FADE_OUT,
75     LV_SCR_LOAD_ANIM_OUT_LEFT,
76     LV_SCR_LOAD_ANIM_OUT_RIGHT,
77     LV_SCR_LOAD_ANIM_OUT_TOP,
78     LV_SCR_LOAD_ANIM_OUT_BOTTOM,
79 } lv_screen_load_anim_t;
80 
81 typedef void (*lv_display_flush_cb_t)(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
82 typedef void (*lv_display_flush_wait_cb_t)(lv_display_t * disp);
83 
84 /**********************
85  * GLOBAL PROTOTYPES
86  **********************/
87 
88 /**
89  * Create a new display with the given resolution
90  * @param hor_res   horizontal resolution in pixels
91  * @param ver_res   vertical resolution in pixels
92  * @return          pointer to a display object or `NULL` on error
93  */
94 lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res);
95 
96 /**
97  * Remove a display
98  * @param disp      pointer to display
99  */
100 void lv_display_delete(lv_display_t * disp);
101 
102 /**
103  * Set a default display. The new screens will be created on it by default.
104  * @param disp      pointer to a display
105  */
106 void lv_display_set_default(lv_display_t * disp);
107 
108 /**
109  * Get the default display
110  * @return          pointer to the default display
111  */
112 lv_display_t * lv_display_get_default(void);
113 
114 /**
115  * Get the next display.
116  * @param disp      pointer to the current display. NULL to initialize.
117  * @return          the next display or NULL if no more. Gives the first display when the parameter is NULL.
118  */
119 lv_display_t * lv_display_get_next(lv_display_t * disp);
120 
121 /*---------------------
122  * RESOLUTION
123  *--------------------*/
124 
125 /**
126  * Sets the resolution of a display. `LV_EVENT_RESOLUTION_CHANGED` event will be sent.
127  * Here the native resolution of the device should be set. If the display will be rotated later with
128  * `lv_display_set_rotation` LVGL will swap the hor. and ver. resolution automatically.
129  * @param disp      pointer to a display
130  * @param hor_res   the new horizontal resolution
131  * @param ver_res   the new vertical resolution
132  */
133 void lv_display_set_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res);
134 
135 /**
136  * It's not mandatory to use the whole display for LVGL, however in some cases physical resolution is important.
137  * For example the touchpad still sees whole resolution and the values needs to be converted
138  * to the active LVGL display area.
139  * @param disp      pointer to a display
140  * @param hor_res   the new physical horizontal resolution, or -1 to assume it's the same as the normal hor. res.
141  * @param ver_res   the new physical vertical resolution, or -1 to assume it's the same as the normal hor. res.
142  */
143 void lv_display_set_physical_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res);
144 
145 /**
146  * If physical resolution is not the same as the normal resolution
147  * the offset of the active display area can be set here.
148  * @param disp      pointer to a display
149  * @param x         X offset
150  * @param y         Y offset
151  */
152 void lv_display_set_offset(lv_display_t * disp, int32_t x, int32_t y);
153 
154 /**
155  * Set the rotation of this display. LVGL will swap the horizontal and vertical resolutions internally.
156  * @param disp      pointer to a display (NULL to use the default display)
157  * @param rotation  `LV_DISPLAY_ROTATION_0/90/180/270`
158  */
159 void lv_display_set_rotation(lv_display_t * disp, lv_display_rotation_t rotation);
160 
161 /**
162  * Set the DPI (dot per inch) of the display.
163  * dpi = sqrt(hor_res^2 + ver_res^2) / diagonal"
164  * @param disp      pointer to a display
165  * @param dpi       the new DPI
166  */
167 void lv_display_set_dpi(lv_display_t * disp, int32_t dpi);
168 
169 /**
170  * Get the horizontal resolution of a display.
171  * @param disp      pointer to a display (NULL to use the default display)
172  * @return          the horizontal resolution of the display.
173  */
174 int32_t lv_display_get_horizontal_resolution(const lv_display_t * disp);
175 
176 /**
177  * Get the vertical resolution of a display
178  * @param disp      pointer to a display (NULL to use the default display)
179  * @return          the vertical resolution of the display
180  */
181 int32_t lv_display_get_vertical_resolution(const lv_display_t * disp);
182 
183 /**
184  * Get the physical horizontal resolution of a display
185  * @param disp      pointer to a display (NULL to use the default display)
186  * @return the      physical horizontal resolution of the display
187  */
188 int32_t lv_display_get_physical_horizontal_resolution(const lv_display_t * disp);
189 
190 /**
191  * Get the physical vertical resolution of a display
192  * @param disp      pointer to a display (NULL to use the default display)
193  * @return          the physical vertical resolution of the display
194  */
195 int32_t lv_display_get_physical_vertical_resolution(const lv_display_t * disp);
196 
197 /**
198  * Get the horizontal offset from the full / physical display
199  * @param disp      pointer to a display (NULL to use the default display)
200  * @return          the horizontal offset from the physical display
201  */
202 int32_t lv_display_get_offset_x(const lv_display_t * disp);
203 
204 /**
205  * Get the vertical offset from the full / physical display
206  * @param disp      pointer to a display (NULL to use the default display)
207  * @return          the horizontal offset from the physical display
208  */
209 int32_t lv_display_get_offset_y(const lv_display_t * disp);
210 
211 /**
212  * Get the current rotation of this display.
213  * @param disp      pointer to a display (NULL to use the default display)
214  * @return          the current rotation
215  */
216 lv_display_rotation_t lv_display_get_rotation(lv_display_t * disp);
217 
218 /**
219  * Get the DPI of the display
220  * @param disp      pointer to a display (NULL to use the default display)
221  * @return          dpi of the display
222  */
223 int32_t lv_display_get_dpi(const lv_display_t * disp);
224 
225 /*---------------------
226  * BUFFERING
227  *--------------------*/
228 
229 /**
230  * Set the buffers for a display, similarly to `lv_display_set_draw_buffers`, but accept the raw buffer pointers.
231  * For DIRECT/FULL rending modes, the buffer size must be at least
232  * `hor_res * ver_res * lv_color_format_get_size(lv_display_get_color_format(disp))`
233  * @param disp              pointer to a display
234  * @param buf1              first buffer
235  * @param buf2              second buffer (can be `NULL`)
236  * @param buf_size          buffer size in byte
237  * @param render_mode       LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL
238  */
239 void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size,
240                             lv_display_render_mode_t render_mode);
241 
242 /**
243  * Set the frame buffers for a display, similarly to `lv_display_set_buffers`, but allow
244  * for a custom stride as required by a display controller.
245  * This allows the frame buffers to have a stride alignment different from the rest of
246  * the buffers`
247  * @param disp              pointer to a display
248  * @param buf1              first buffer
249  * @param buf2              second buffer (can be `NULL`)
250  * @param buf_size          buffer size in byte
251  * @param stride            buffer stride in bytes
252  * @param render_mode       LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL
253  */
254 void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size,
255                                         uint32_t stride, lv_display_render_mode_t render_mode);
256 
257 /**
258  * Set the buffers for a display, accept a draw buffer pointer.
259  * Normally use `lv_display_set_buffers` is enough for most cases.
260  * Use this function when an existing lv_draw_buf_t is available.
261  * @param disp              pointer to a display
262  * @param buf1              first buffer
263  * @param buf2              second buffer (can be `NULL`)
264  */
265 void lv_display_set_draw_buffers(lv_display_t * disp, lv_draw_buf_t * buf1, lv_draw_buf_t * buf2);
266 
267 /**
268  * Set display render mode
269  * @param disp              pointer to a display
270  * @param render_mode       LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL
271  */
272 void lv_display_set_render_mode(lv_display_t * disp, lv_display_render_mode_t render_mode);
273 
274 /**
275  * Set the flush callback which will be called to copy the rendered image to the display.
276  * @param disp      pointer to a display
277  * @param flush_cb  the flush callback (`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display)
278  */
279 void lv_display_set_flush_cb(lv_display_t * disp, lv_display_flush_cb_t flush_cb);
280 
281 /**
282  * Set a callback to be used while LVGL is waiting flushing to be finished.
283  * It can do any complex logic to wait, including semaphores, mutexes, polling flags, etc.
284  * If not set the `disp->flushing` flag is used which can be cleared with `lv_display_flush_ready()`
285  * @param disp      pointer to a display
286  * @param wait_cb   a callback to call while LVGL is waiting for flush ready.
287  *                  If NULL `lv_display_flush_ready()` can be used to signal that flushing is ready.
288  */
289 void lv_display_set_flush_wait_cb(lv_display_t * disp, lv_display_flush_wait_cb_t wait_cb);
290 
291 /**
292  * Set the color format of the display.
293  * @param disp              pointer to a display
294  * @param color_format      Possible values are
295  *                          - LV_COLOR_FORMAT_RGB565
296  *                          - LV_COLOR_FORMAT_RGB888
297  *                          - LV_COLOR_FORMAT_XRGB888
298  *                          - LV_COLOR_FORMAT_ARGB888
299  *@note To change the endianness of the rendered image in case of RGB565 format
300  *      (i.e. swap the 2 bytes) call `lv_draw_sw_rgb565_swap` in the flush_cb
301  */
302 void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_format);
303 
304 /**
305  * Get the color format of the display
306  * @param disp              pointer to a display
307  * @return                  the color format
308  */
309 lv_color_format_t lv_display_get_color_format(lv_display_t * disp);
310 
311 /**
312  * Set the number of tiles for parallel rendering.
313  * @param disp              pointer to a display
314  * @param tile_cnt          number of tiles (1 =< tile_cnt < 256)
315  */
316 void lv_display_set_tile_cnt(lv_display_t * disp, uint32_t tile_cnt);
317 
318 /**
319  * Get the number of tiles used for parallel rendering
320  * @param disp              pointer to a display
321  * @return                  number of tiles
322  */
323 uint32_t lv_display_get_tile_cnt(lv_display_t * disp);
324 
325 /**
326  * Enable anti-aliasing for the render engine
327  * @param disp      pointer to a display
328  * @param en        true/false
329  */
330 void lv_display_set_antialiasing(lv_display_t * disp, bool en);
331 
332 /**
333  * Get if anti-aliasing is enabled for a display or not
334  * @param disp      pointer to a display (NULL to use the default display)
335  * @return          true/false
336  */
337 bool lv_display_get_antialiasing(lv_display_t * disp);
338 
339 //! @cond Doxygen_Suppress
340 
341 /**
342  * Call from the display driver when the flushing is finished
343  * @param disp      pointer to display whose `flush_cb` was called
344  */
345 LV_ATTRIBUTE_FLUSH_READY void lv_display_flush_ready(lv_display_t * disp);
346 
347 /**
348  * Tell if it's the last area of the refreshing process.
349  * Can be called from `flush_cb` to execute some special display refreshing if needed when all areas area flushed.
350  * @param disp      pointer to display
351  * @return          true: it's the last area to flush;
352  *                  false: there are other areas too which will be refreshed soon
353  */
354 LV_ATTRIBUTE_FLUSH_READY bool lv_display_flush_is_last(lv_display_t * disp);
355 
356 //! @endcond
357 
358 bool lv_display_is_double_buffered(lv_display_t * disp);
359 
360 /*---------------------
361  * SCREENS
362  *--------------------*/
363 
364 /**
365  * Return a pointer to the active screen on a display
366  * @param disp      pointer to display which active screen should be get.
367  *                  (NULL to use the default screen)
368  * @return          pointer to the active screen object (loaded by 'lv_screen_load()')
369  */
370 lv_obj_t * lv_display_get_screen_active(lv_display_t * disp);
371 
372 /**
373  * Return with a pointer to the previous screen. Only used during screen transitions.
374  * @param disp      pointer to display which previous screen should be get.
375  *                  (NULL to use the default screen)
376  * @return          pointer to the previous screen object or NULL if not used now
377  */
378 lv_obj_t * lv_display_get_screen_prev(lv_display_t * disp);
379 
380 /**
381  * Return the top layer. The top layer is the same on all screens and it is above the normal screen layer.
382  * @param disp      pointer to display which top layer should be get. (NULL to use the default screen)
383  * @return          pointer to the top layer object
384  */
385 lv_obj_t * lv_display_get_layer_top(lv_display_t * disp);
386 
387 /**
388  * Return the sys. layer. The system layer is the same on all screen and it is above the normal screen and the top layer.
389  * @param disp      pointer to display which sys. layer should be retrieved. (NULL to use the default screen)
390  * @return          pointer to the sys layer object
391  */
392 lv_obj_t * lv_display_get_layer_sys(lv_display_t * disp);
393 
394 /**
395  * Return the bottom layer. The bottom layer is the same on all screen and it is under the normal screen layer.
396  * It's visible only if the screen is transparent.
397  * @param disp      pointer to display (NULL to use the default screen)
398  * @return          pointer to the bottom layer object
399  */
400 lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp);
401 
402 /**
403  * Load a screen on the default display
404  * @param scr       pointer to a screen
405  */
406 void lv_screen_load(struct _lv_obj_t * scr);
407 
408 /**
409  * Switch screen with animation
410  * @param scr       pointer to the new screen to load
411  * @param anim_type type of the animation from `lv_screen_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
412  * @param time      time of the animation
413  * @param delay     delay before the transition
414  * @param auto_del  true: automatically delete the old screen
415  */
416 void lv_screen_load_anim(lv_obj_t * scr, lv_screen_load_anim_t anim_type, uint32_t time, uint32_t delay,
417                          bool auto_del);
418 
419 /**
420  * Get the active screen of the default display
421  * @return          pointer to the active screen
422  */
423 lv_obj_t * lv_screen_active(void);
424 
425 /**
426  * Get the top layer  of the default display
427  * @return          pointer to the top layer
428  */
429 lv_obj_t * lv_layer_top(void);
430 
431 /**
432  * Get the system layer  of the default display
433  * @return          pointer to the sys layer
434  */
435 lv_obj_t * lv_layer_sys(void);
436 
437 /**
438  * Get the bottom layer  of the default display
439  * @return          pointer to the bottom layer
440  */
441 lv_obj_t * lv_layer_bottom(void);
442 
443 /*---------------------
444  * OTHERS
445  *--------------------*/
446 
447 /**
448  * Add an event handler to the display
449  * @param disp          pointer to a display
450  * @param event_cb      an event callback
451  * @param filter        event code to react or `LV_EVENT_ALL`
452  * @param user_data     optional user_data
453  */
454 void lv_display_add_event_cb(lv_display_t * disp, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data);
455 
456 /**
457  * Get the number of event attached to a display
458  * @param disp          pointer to a display
459  * @return              number of events
460  */
461 uint32_t lv_display_get_event_count(lv_display_t * disp);
462 
463 /**
464  * Get an event descriptor for an event
465  * @param disp          pointer to a display
466  * @param index         the index of the event
467  * @return              the event descriptor
468  */
469 lv_event_dsc_t * lv_display_get_event_dsc(lv_display_t * disp, uint32_t index);
470 
471 /**
472  * Remove an event
473  * @param disp          pointer to a display
474  * @param index         the index of the event to remove
475  * @return              true: and event was removed; false: no event was removed
476  */
477 bool lv_display_delete_event(lv_display_t * disp, uint32_t index);
478 
479 /**
480  * Remove an event_cb with user_data
481  * @param disp          pointer to a display
482  * @param event_cb      the event_cb of the event to remove
483  * @param user_data     user_data
484  * @return              the count of the event removed
485  */
486 uint32_t lv_display_remove_event_cb_with_user_data(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data);
487 
488 /**
489  * Send an event to a display
490  * @param disp          pointer to a display
491  * @param code          an event code. LV_EVENT_...
492  * @param param         optional param
493  * @return              LV_RESULT_OK: disp wasn't deleted in the event.
494  */
495 lv_result_t lv_display_send_event(lv_display_t * disp, lv_event_code_t code, void * param);
496 
497 /**
498  * Get the area to be invalidated. Can be used in `LV_EVENT_INVALIDATE_AREA`
499  * @param e     pointer to an event
500  * @return      the area to invalidated (can be modified as required)
501  */
502 lv_area_t * lv_event_get_invalidated_area(lv_event_t * e);
503 
504 /**
505  * Set the theme of a display. If there are no user created widgets yet the screens' theme will be updated
506  * @param disp      pointer to a display
507  * @param th        pointer to a theme
508  */
509 void lv_display_set_theme(lv_display_t * disp, lv_theme_t * th);
510 
511 /**
512  * Get the theme of a display
513  * @param disp      pointer to a display
514  * @return          the display's theme (can be NULL)
515  */
516 lv_theme_t * lv_display_get_theme(lv_display_t * disp);
517 
518 /**
519  * Get elapsed time since last user activity on a display (e.g. click)
520  * @param disp      pointer to a display (NULL to get the overall smallest inactivity)
521  * @return          elapsed ticks (milliseconds) since the last activity
522  */
523 uint32_t lv_display_get_inactive_time(const lv_display_t * disp);
524 
525 /**
526  * Manually trigger an activity on a display
527  * @param disp      pointer to a display (NULL to use the default display)
528  */
529 void lv_display_trigger_activity(lv_display_t * disp);
530 
531 /**
532  * Temporarily enable and disable the invalidation of the display.
533  * @param disp      pointer to a display (NULL to use the default display)
534  * @param en        true: enable invalidation; false: invalidation
535  */
536 void lv_display_enable_invalidation(lv_display_t * disp, bool en);
537 
538 /**
539  * Get display invalidation is enabled.
540  * @param disp      pointer to a display (NULL to use the default display)
541  * @return return   true if invalidation is enabled
542  */
543 bool lv_display_is_invalidation_enabled(lv_display_t * disp);
544 
545 /**
546  * Get a pointer to the screen refresher timer to
547  * modify its parameters with `lv_timer_...` functions.
548  * @param disp      pointer to a display
549  * @return          pointer to the display refresher timer. (NULL on error)
550  */
551 lv_timer_t * lv_display_get_refr_timer(lv_display_t * disp);
552 
553 /**
554  * Delete screen refresher timer
555  * @param disp      pointer to a display
556  */
557 void lv_display_delete_refr_timer(lv_display_t * disp);
558 
559 void lv_display_set_user_data(lv_display_t * disp, void * user_data);
560 void lv_display_set_driver_data(lv_display_t * disp, void * driver_data);
561 void * lv_display_get_user_data(lv_display_t * disp);
562 void * lv_display_get_driver_data(lv_display_t * disp);
563 lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp);
564 
565 /**
566  * Rotate an area in-place according to the display's rotation
567  * @param disp      pointer to a display
568  * @param area      pointer to an area to rotate
569  */
570 void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area);
571 
572 /**
573  * Get the size of the draw buffers
574  * @param disp      pointer to a display
575  * @return          the size of the draw buffer in bytes for valid display, 0 otherwise
576  */
577 uint32_t lv_display_get_draw_buf_size(lv_display_t * disp);
578 
579 /**
580  * Get the size of the invalidated draw buffer. Can be used in the flush callback
581  * to get the number of bytes used in the current render buffer.
582  * @param disp      pointer to a display
583  * @param width     the width of the invalidated area
584  * @param height    the height of the invalidated area
585  * @return          the size of the invalidated draw buffer in bytes, not accounting for
586  *                  any preceding palette information for a valid display, 0 otherwise
587  */
588 uint32_t lv_display_get_invalidated_draw_buf_size(lv_display_t * disp, uint32_t width, uint32_t height);
589 
590 /**********************
591  *      MACROS
592  **********************/
593 
594 /*------------------------------------------------
595  * To improve backward compatibility
596  * Recommended only if you have one display
597  *------------------------------------------------*/
598 
599 #ifndef LV_HOR_RES
600 /**
601  * The horizontal resolution of the currently active display.
602  */
603 #define LV_HOR_RES lv_display_get_horizontal_resolution(lv_display_get_default())
604 #endif
605 
606 #ifndef LV_VER_RES
607 /**
608  * The vertical resolution of the currently active display.
609  */
610 #define LV_VER_RES lv_display_get_vertical_resolution(lv_display_get_default())
611 #endif
612 
613 /**
614  * See `lv_dpx()` and `lv_display_dpx()`.
615  * Same as Android's DIP. (Different name is chosen to avoid mistype between LV_DPI and LV_DIP)
616  *
617  * - 40 dip is 40 px on a 160 DPI screen (distance = 1/4 inch).
618  * - 40 dip is 80 px on a 320 DPI screen (distance still = 1/4 inch).
619  *
620  * @sa https://stackoverflow.com/questions/2025282/what-is-the-difference-between-px-dip-dp-and-sp
621  */
622 #define LV_DPX_CALC(dpi, n)   ((n) == 0 ? 0 :LV_MAX((( (dpi) * (n) + 80) / 160), 1)) /*+80 for rounding*/
623 #define LV_DPX(n)   LV_DPX_CALC(lv_display_get_dpi(NULL), n)
624 
625 /**
626  * For default display, computes the number of pixels (a distance or size) as if the
627  * display had 160 DPI.  This allows you to specify 1/160-th fractions of an inch to
628  * get real distance on the display that will be consistent regardless of its current
629  * DPI.  It ensures `lv_dpx(100)`, for example, will have the same physical size
630  * regardless to the DPI of the display.
631  * @param n     number of 1/160-th-inch units to compute with
632  * @return      number of pixels to use to make that distance
633  */
634 int32_t lv_dpx(int32_t n);
635 
636 /**
637  * For specified display, computes the number of pixels (a distance or size) as if the
638  * display had 160 DPI.  This allows you to specify 1/160-th fractions of an inch to
639  * get real distance on the display that will be consistent regardless of its current
640  * DPI.  It ensures `lv_dpx(100)`, for example, will have the same physical size
641  * regardless to the DPI of the display.
642  * @param disp  pointer to display whose dpi should be considered
643  * @param n     number of 1/160-th-inch units to compute with
644  * @return      number of pixels to use to make that distance
645  */
646 int32_t lv_display_dpx(const lv_display_t * disp, int32_t n);
647 
648 #ifdef __cplusplus
649 } /*extern "C"*/
650 #endif
651 
652 #endif /*LV_DISPLAY_H*/
653