From 91cd8ecf907dade7b5367c2e0f60936a84a004da Mon Sep 17 00:00:00 2001 From: elahav Date: Thu, 25 Jul 2024 08:26:09 -0400 Subject: [PATCH] feat(drivers): initial implementation of a QNX screen driver (#6507) Co-authored-by: Elad Lahav --- Kconfig | 9 + docs/integration/os/qnx.rst | 123 +++ env_support/qnx/Makefile | 2 + env_support/qnx/aarch64/Makefile | 2 + env_support/qnx/aarch64/a.le/Makefile | 1 + env_support/qnx/aarch64/so.le/Makefile | 1 + env_support/qnx/common.mk | 113 +++ env_support/qnx/lv_conf.h | 1075 ++++++++++++++++++++++++ env_support/qnx/x86_64/Makefile | 2 + env_support/qnx/x86_64/a/Makefile | 1 + env_support/qnx/x86_64/so/Makefile | 1 + lv_conf_template.h | 6 + src/drivers/lv_drivers.h | 2 + src/drivers/qnx/lv_qnx.c | 542 ++++++++++++ src/drivers/qnx/lv_qnx.h | 86 ++ src/lv_conf_internal.h | 22 + 16 files changed, 1988 insertions(+) create mode 100644 docs/integration/os/qnx.rst create mode 100644 env_support/qnx/Makefile create mode 100644 env_support/qnx/aarch64/Makefile create mode 100644 env_support/qnx/aarch64/a.le/Makefile create mode 100644 env_support/qnx/aarch64/so.le/Makefile create mode 100644 env_support/qnx/common.mk create mode 100644 env_support/qnx/lv_conf.h create mode 100644 env_support/qnx/x86_64/Makefile create mode 100644 env_support/qnx/x86_64/a/Makefile create mode 100644 env_support/qnx/x86_64/so/Makefile create mode 100644 src/drivers/qnx/lv_qnx.c create mode 100644 src/drivers/qnx/lv_qnx.h diff --git a/Kconfig b/Kconfig index ff8ab620f..2c61dfeba 100644 --- a/Kconfig +++ b/Kconfig @@ -1724,6 +1724,15 @@ menu "LVGL configuration" bool "Enable debug mode for OpenGL" depends on LV_USE_OPENGLES default n + + config LV_USE_QNX + bool "Use a QNX Screen window as a display" + default n + + config LV_QNX_BUF_COUNT + int + depends on LV_USE_QNX + default 1 endmenu menu "Examples" diff --git a/docs/integration/os/qnx.rst b/docs/integration/os/qnx.rst new file mode 100644 index 000000000..2fd3f3d34 --- /dev/null +++ b/docs/integration/os/qnx.rst @@ -0,0 +1,123 @@ +=== +QNX +=== + +What is QNX? +------------ + +QNX is a commercial operating system first released in 1980. The operating +system is based on a micro-kernel design, with the file system(s), network +stack, and various other drivers each running in its own process with a separate +address space. + +See www.qnx.com for more details. + +Highlight of QNX +~~~~~~~~~~~~~~~~ + +- 64-bit only, runs on x86_64 and ARMv8 +- Requires an MMU as the design mandates separation among processes +- Support for thousands of processes and millions of threads +- Up to 64 cores, up to 16TB of RAM +- Virtualization support (as host and guest) +- Full POSIX compatibility +- Safety certification to various automotive, industrial and medical standards + +How to run LVGL on QNX? +----------------------- + +Build LVGL +~~~~~~~~~~ + +The top-level `qnx` directory includes a recursive make file for building LVGL, +both as a shared library and as a static library for the supported +architectures. To build all libraries, simply invoke `make` in this directory: + +.. code:: shell + + # cd $(LVGL_ROOT)/qnx + # make + +If you prefer to build for a specific architecture and variant, go to the +appropriate directory and run `make` there. For example, to build a shared +library for ARMv8: + +.. code:: shell + + # cd $(LVGL_ROOT)/qnx/aarch64/so.le + # make + +As a general rule, if you only want to have one LVGL application in your system +then it is better to use a static library. If you have more than one, and +especially if they run concurrently, it is better to use the shared library. + +Before building the library, you may wish to edit `$(LVGL_ROOT)/qnx/lv_conf.h`, +e.g. to enable double-buffering. + +Writing a LVGL Application +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To create a LVGL application for QNX, follow these steps in your code: + +1. Initialize the library. +2. Create a window. +3. Add the input devices. +4. Create the UI. +5. Run the event loop. + +Steps 2, 3 and 5 use QNX-specific calls, but the rest of the code should be +identical to that of a LVGL application written for any other platform. + +The following code shows how to create a "Hello World" application: + +.. code:: c + + #include + + int + main(int argc, char **argv) + { + /* Initialize the library. */ + lv_init(); + + /* Create a 800x480 window. */ + lv_display_t *disp = lv_qnx_window_create(800, 480); + lv_qnx_window_set_title(disp, "LVGL Example"); + + /* Add a keyboard and mouse devices. */ + lv_qnx_add_keyboard_device(disp); + lv_qnx_add_pointer_device(disp); + + /* Generate the UI. */ + lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN); + + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_text(label, "Hello world"); + lv_obj_set_style_text_color(lv_screen_active(), lv_color_hex(0xffffff), LV_PART_MAIN); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + + /* Run the event loop until it exits. */ + return lv_qnx_event_loop(disp); + } + +Build the Application +~~~~~~~~~~~~~~~~~~~~~ + +Building the application consists of compiling the source with the LVGL headers, +and then linking against the library. This can be done in many ways, using +different build systems. The following is a simple make file for the example +above, which builds for ARMv8 with the shared library: + +.. code:: makefile + + CC=qcc -Vgcc_ntoaarch64le + + LVGL_DIR=$(HOME)/src/lvgl + CCFLAGS=-I$(LVGL_DIR)/qnx -I$(LVGL_DIR) + LDFLAGS=-lscreen -llvgl -L$(LVGL_DIR)/qnx/aarch64/so.le + + lvgl_example: lvgl_example.c + $(CC) $(CCFLAGS) -Wall -o $@ $< $(LDFLAGS) + + clean: + rm -f *.o *~ lvgl_example diff --git a/env_support/qnx/Makefile b/env_support/qnx/Makefile new file mode 100644 index 000000000..074b0d52a --- /dev/null +++ b/env_support/qnx/Makefile @@ -0,0 +1,2 @@ +LIST=CPU +include recurse.mk diff --git a/env_support/qnx/aarch64/Makefile b/env_support/qnx/aarch64/Makefile new file mode 100644 index 000000000..c95a66648 --- /dev/null +++ b/env_support/qnx/aarch64/Makefile @@ -0,0 +1,2 @@ +LIST=VARIANT +include recurse.mk diff --git a/env_support/qnx/aarch64/a.le/Makefile b/env_support/qnx/aarch64/a.le/Makefile new file mode 100644 index 000000000..2c760893e --- /dev/null +++ b/env_support/qnx/aarch64/a.le/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/env_support/qnx/aarch64/so.le/Makefile b/env_support/qnx/aarch64/so.le/Makefile new file mode 100644 index 000000000..2c760893e --- /dev/null +++ b/env_support/qnx/aarch64/so.le/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/env_support/qnx/common.mk b/env_support/qnx/common.mk new file mode 100644 index 000000000..4d44f72c7 --- /dev/null +++ b/env_support/qnx/common.mk @@ -0,0 +1,113 @@ +ifndef QCONFIG +QCONFIG=qconfig.mk +endif +include $(QCONFIG) + +define PINFO +PINFO DESCRIPTION = Light and Versatile Graphics Library +endef +INSTALLDIR= +NAME=lvgl +USEFILE= + +SRC_ROOT=$(PROJECT_ROOT)/../../src +EXTRA_SRCVPATH=$(SRC_ROOT) \ +$(SRC_ROOT)/libs \ +$(SRC_ROOT)/libs/bmp \ +$(SRC_ROOT)/libs/libjpeg_turbo \ +$(SRC_ROOT)/libs/fsdrv \ +$(SRC_ROOT)/libs/libpng \ +$(SRC_ROOT)/libs/bin_decoder \ +$(SRC_ROOT)/libs/tiny_ttf \ +$(SRC_ROOT)/libs/barcode \ +$(SRC_ROOT)/libs/rlottie \ +$(SRC_ROOT)/libs/qrcode \ +$(SRC_ROOT)/libs/lz4 \ +$(SRC_ROOT)/libs/ffmpeg \ +$(SRC_ROOT)/libs/tjpgd \ +$(SRC_ROOT)/libs/thorvg \ +$(SRC_ROOT)/libs/thorvg/rapidjson \ +$(SRC_ROOT)/libs/thorvg/rapidjson/internal \ +$(SRC_ROOT)/libs/thorvg/rapidjson/error \ +$(SRC_ROOT)/libs/lodepng \ +$(SRC_ROOT)/libs/rle \ +$(SRC_ROOT)/libs/gif \ +$(SRC_ROOT)/libs/freetype \ +$(SRC_ROOT)/draw \ +$(SRC_ROOT)/draw/vg_lite \ +$(SRC_ROOT)/draw/sw \ +$(SRC_ROOT)/draw/sw/arm2d \ +$(SRC_ROOT)/draw/sw/blend \ +$(SRC_ROOT)/draw/sw/blend/helium \ +$(SRC_ROOT)/draw/sw/blend/arm2d \ +$(SRC_ROOT)/draw/sw/blend/neon \ +$(SRC_ROOT)/misc \ +$(SRC_ROOT)/misc/cache \ +$(SRC_ROOT)/font \ +$(SRC_ROOT)/stdlib \ +$(SRC_ROOT)/stdlib/builtin \ +$(SRC_ROOT)/stdlib/rtthread \ +$(SRC_ROOT)/stdlib/clib \ +$(SRC_ROOT)/stdlib/micropython \ +$(SRC_ROOT)/drivers \ +$(SRC_ROOT)/drivers/qnx \ +$(SRC_ROOT)/themes \ +$(SRC_ROOT)/themes/simple \ +$(SRC_ROOT)/themes/mono \ +$(SRC_ROOT)/themes/default \ +$(SRC_ROOT)/display \ +$(SRC_ROOT)/indev \ +$(SRC_ROOT)/core \ +$(SRC_ROOT)/tick \ +$(SRC_ROOT)/others \ +$(SRC_ROOT)/others/monkey \ +$(SRC_ROOT)/others/ime \ +$(SRC_ROOT)/others/snapshot \ +$(SRC_ROOT)/others/file_explorer \ +$(SRC_ROOT)/others/imgfont \ +$(SRC_ROOT)/others/fragment \ +$(SRC_ROOT)/others/observer \ +$(SRC_ROOT)/others/vg_lite_tvg \ +$(SRC_ROOT)/others/sysmon \ +$(SRC_ROOT)/others/gridnav \ +$(SRC_ROOT)/widgets \ +$(SRC_ROOT)/widgets/objx_templ \ +$(SRC_ROOT)/widgets/tabview \ +$(SRC_ROOT)/widgets/scale \ +$(SRC_ROOT)/widgets/checkbox \ +$(SRC_ROOT)/widgets/slider \ +$(SRC_ROOT)/widgets/calendar \ +$(SRC_ROOT)/widgets/bar \ +$(SRC_ROOT)/widgets/win \ +$(SRC_ROOT)/widgets/dropdown \ +$(SRC_ROOT)/widgets/switch \ +$(SRC_ROOT)/widgets/span \ +$(SRC_ROOT)/widgets/canvas \ +$(SRC_ROOT)/widgets/lottie \ +$(SRC_ROOT)/widgets/textarea \ +$(SRC_ROOT)/widgets/arc \ +$(SRC_ROOT)/widgets/msgbox \ +$(SRC_ROOT)/widgets/property \ +$(SRC_ROOT)/widgets/chart \ +$(SRC_ROOT)/widgets/table \ +$(SRC_ROOT)/widgets/list \ +$(SRC_ROOT)/widgets/button \ +$(SRC_ROOT)/widgets/image \ +$(SRC_ROOT)/widgets/line \ +$(SRC_ROOT)/widgets/animimage \ +$(SRC_ROOT)/widgets/roller \ +$(SRC_ROOT)/widgets/spinner \ +$(SRC_ROOT)/widgets/imagebutton \ +$(SRC_ROOT)/widgets/led \ +$(SRC_ROOT)/widgets/spinbox \ +$(SRC_ROOT)/widgets/keyboard \ +$(SRC_ROOT)/widgets/buttonmatrix \ +$(SRC_ROOT)/widgets/menu \ +$(SRC_ROOT)/widgets/label \ +$(SRC_ROOT)/widgets/tileview \ +$(SRC_ROOT)/layouts \ +$(SRC_ROOT)/layouts/grid \ +$(SRC_ROOT)/layouts/flex \ +$(SRC_ROOT)/osal + +include $(MKFILES_ROOT)/qtargets.mk diff --git a/env_support/qnx/lv_conf.h b/env_support/qnx/lv_conf.h new file mode 100644 index 000000000..5d8377422 --- /dev/null +++ b/env_support/qnx/lv_conf.h @@ -0,0 +1,1075 @@ +/** + * @file lv_conf.h + * Configuration file for v9.1.1-dev + */ + +/* + * Copy this file as `lv_conf.h` + * 1. simply next to the `lvgl` folder + * 2. or any other places and + * - define `LV_CONF_INCLUDE_SIMPLE` + * - add the path as include path + */ + +/* clang-format off */ +#if 1 /*Set it to "1" to enable content*/ + +#ifndef LV_CONF_H +#define LV_CONF_H + +/*If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ +#if 0 && defined(__ASSEMBLY__) +#include "my_include.h" +#endif + +/*==================== + COLOR SETTINGS + *====================*/ + +/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +#define LV_COLOR_DEPTH 32 + +/*========================= + STDLIB WRAPPER SETTINGS + *=========================*/ + +/* Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN +#define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN +#define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN + +#define LV_STDINT_INCLUDE +#define LV_STDDEF_INCLUDE +#define LV_STDBOOL_INCLUDE +#define LV_INTTYPES_INCLUDE +#define LV_LIMITS_INCLUDE +#define LV_STDARG_INCLUDE + +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ + #define LV_MEM_SIZE (64 * 1024U) /*[bytes]*/ + + /*Size of the memory expand for `lv_malloc()` in bytes*/ + #define LV_MEM_POOL_EXPAND_SIZE 0 + + /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ + #define LV_MEM_ADR 0 /*0: unused*/ + /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/ + #if LV_MEM_ADR == 0 + #undef LV_MEM_POOL_INCLUDE + #undef LV_MEM_POOL_ALLOC + #endif +#endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/ + +/*==================== + HAL SETTINGS + *====================*/ + +/*Default display refresh, input device read and animation step period.*/ +#define LV_DEF_REFR_PERIOD 33 /*[ms]*/ + +/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. + *(Not so important, you can adjust it to modify default sizes and spaces)*/ +#define LV_DPI_DEF 130 /*[px/inch]*/ + +/*================= + * OPERATING SYSTEM + *=================*/ +/*Select an operating system to use. Possible options: + * - LV_OS_NONE + * - LV_OS_PTHREAD + * - LV_OS_FREERTOS + * - LV_OS_CMSIS_RTOS2 + * - LV_OS_RTTHREAD + * - LV_OS_WINDOWS + * - LV_OS_MQX + * - LV_OS_CUSTOM */ +#define LV_USE_OS LV_OS_NONE + +#if LV_USE_OS == LV_OS_CUSTOM + #define LV_OS_CUSTOM_INCLUDE +#endif + +/*======================== + * RENDERING CONFIGURATION + *========================*/ + +/*Align the stride of all layers and images to this bytes*/ +#define LV_DRAW_BUF_STRIDE_ALIGN 1 + +/*Align the start address of draw_buf addresses to this bytes*/ +#define LV_DRAW_BUF_ALIGN 4 + +/* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode + * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. + * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers + * and can't be drawn in chunks. */ + +/*The target buffer size for simple layer chunks.*/ +#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ + +/* The stack size of the drawing thread. + * NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more. + */ +#define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /*[bytes]*/ + +#define LV_USE_DRAW_SW 1 +#if LV_USE_DRAW_SW == 1 + + /* + * Selectively disable color format support in order to reduce code size. + * NOTE: some features use certain color formats internally, e.g. + * - gradients use RGB888 + * - bitmaps with transparency may use ARGB8888 + */ + + #define LV_DRAW_SW_SUPPORT_RGB565 1 + #define LV_DRAW_SW_SUPPORT_RGB565A8 1 + #define LV_DRAW_SW_SUPPORT_RGB888 1 + #define LV_DRAW_SW_SUPPORT_XRGB8888 1 + #define LV_DRAW_SW_SUPPORT_ARGB8888 1 + #define LV_DRAW_SW_SUPPORT_L8 1 + #define LV_DRAW_SW_SUPPORT_AL88 1 + #define LV_DRAW_SW_SUPPORT_A8 1 + + /* Set the number of draw unit. + * > 1 requires an operating system enabled in `LV_USE_OS` + * > 1 means multiple threads will render the screen in parallel */ + #define LV_DRAW_SW_DRAW_UNIT_CNT 1 + + /* Use Arm-2D to accelerate the sw render */ + #define LV_USE_DRAW_ARM2D_SYNC 0 + + /* Enable native helium assembly to be compiled */ + #define LV_USE_NATIVE_HELIUM_ASM 0 + + /* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only + * 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */ + #define LV_DRAW_SW_COMPLEX 1 + + #if LV_DRAW_SW_COMPLEX == 1 + /*Allow buffering some shadow calculation. + *LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius` + *Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/ + #define LV_DRAW_SW_SHADOW_CACHE_SIZE 0 + + /* Set number of maximally cached circle data. + * The circumference of 1/4 circle are saved for anti-aliasing + * radius * 4 bytes are used per circle (the most often used radiuses are saved) + * 0: to disable caching */ + #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 + #endif + + #define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE + + #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM + #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" + #endif + + /* Enable drawing complex gradients in software: linear at an angle, radial or conical */ + #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 0 +#endif + +/* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ +#define LV_USE_DRAW_VGLITE 0 + +#if LV_USE_DRAW_VGLITE + /* Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ + #define LV_USE_VGLITE_BLIT_SPLIT 0 + + #if LV_USE_OS + /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ + #define LV_USE_VGLITE_DRAW_ASYNC 1 + #endif + + /* Enable VGLite asserts. */ + #define LV_USE_VGLITE_ASSERT 0 +#endif + +/* Use NXP's PXP on iMX RTxxx platforms. */ +#define LV_USE_DRAW_PXP 0 + +#if LV_USE_DRAW_PXP + /* Enable PXP asserts. */ + #define LV_USE_PXP_ASSERT 0 +#endif + +/* Use Renesas Dave2D on RA platforms. */ +#define LV_USE_DRAW_DAVE2D 0 + +/* Draw using cached SDL textures*/ +#define LV_USE_DRAW_SDL 0 + +/* Use VG-Lite GPU. */ +#define LV_USE_DRAW_VG_LITE 0 + +#if LV_USE_DRAW_VG_LITE +/* Enable VG-Lite custom external 'gpu_init()' function */ +#define LV_VG_LITE_USE_GPU_INIT 0 + +/* Enable VG-Lite assert. */ +#define LV_VG_LITE_USE_ASSERT 0 + +/* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ +#define LV_VG_LITE_FLUSH_MAX_COUNT 8 + +/* Enable border to simulate shadow + * NOTE: which usually improves performance, + * but does not guarantee the same rendering quality as the software. */ +#define LV_VG_LITE_USE_BOX_SHADOW 0 + +/* VG-Lite gradient maximum cache number. + * NOTE: The memory usage of a single gradient image is 4K bytes. + */ +#define LV_VG_LITE_GRAD_CACHE_CNT 32 + +#endif + +/*======================= + * FEATURE CONFIGURATION + *=======================*/ + +/*------------- + * Logging + *-----------*/ + +/*Enable the log module*/ +#define LV_USE_LOG 0 +#if LV_USE_LOG + + /*How important log should be added: + *LV_LOG_LEVEL_TRACE A lot of logs to give detailed information + *LV_LOG_LEVEL_INFO Log important events + *LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem + *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail + *LV_LOG_LEVEL_USER Only logs added by the user + *LV_LOG_LEVEL_NONE Do not log anything*/ + #define LV_LOG_LEVEL LV_LOG_LEVEL_INFO + + /*1: Print the log with 'printf'; + *0: User need to register a callback with `lv_log_register_print_cb()`*/ + #define LV_LOG_PRINTF 1 + + /*Set callback to print the logs. + *E.g `my_print`. The prototype should be `void my_print(lv_log_level_t level, const char * buf)` + *Can be overwritten by `lv_log_register_print_cb`*/ + //#define LV_LOG_PRINT_CB + + /*1: Enable print timestamp; + *0: Disable print timestamp*/ + #define LV_LOG_USE_TIMESTAMP 1 + + /*1: Print file and line number of the log; + *0: Do not print file and line number of the log*/ + #define LV_LOG_USE_FILE_LINE 1 + + + /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ + #define LV_LOG_TRACE_MEM 1 + #define LV_LOG_TRACE_TIMER 1 + #define LV_LOG_TRACE_INDEV 1 + #define LV_LOG_TRACE_DISP_REFR 1 + #define LV_LOG_TRACE_EVENT 1 + #define LV_LOG_TRACE_OBJ_CREATE 1 + #define LV_LOG_TRACE_LAYOUT 1 + #define LV_LOG_TRACE_ANIM 1 + #define LV_LOG_TRACE_CACHE 1 + +#endif /*LV_USE_LOG*/ + +/*------------- + * Asserts + *-----------*/ + +/*Enable asserts if an operation is failed or an invalid data is found. + *If LV_USE_LOG is enabled an error message will be printed on failure*/ +#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/ +#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/ +#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/ +#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ +#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ + +/*Add a custom handler when assert happens e.g. to restart the MCU*/ +#define LV_ASSERT_HANDLER_INCLUDE +#define LV_ASSERT_HANDLER while(1); /*Halt by default*/ + +/*------------- + * Debug + *-----------*/ + +/*1: Draw random colored rectangles over the redrawn areas*/ +#define LV_USE_REFR_DEBUG 0 + +/*1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ +#define LV_USE_LAYER_DEBUG 0 + +/*1: Draw overlays with different colors for each draw_unit's tasks. + *Also add the index number of the draw unit on white background. + *For layers add the index number of the draw unit on black background.*/ +#define LV_USE_PARALLEL_DRAW_DEBUG 0 + +/*------------- + * Others + *-----------*/ + +#define LV_ENABLE_GLOBAL_CUSTOM 0 +#if LV_ENABLE_GLOBAL_CUSTOM + /*Header to include for the custom 'lv_global' function"*/ + #define LV_GLOBAL_CUSTOM_INCLUDE +#endif + +/*Default cache size in bytes. + *Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory. + *If size is not set to 0, the decoder will fail to decode when the cache is full. + *If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/ +#define LV_CACHE_DEF_SIZE 0 + +/*Default number of image header cache entries. The cache is used to store the headers of images + *The main logic is like `LV_CACHE_DEF_SIZE` but for image headers.*/ +#define LV_IMAGE_HEADER_CACHE_DEF_CNT 0 + +/*Number of stops allowed per gradient. Increase this to allow more stops. + *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ +#define LV_GRADIENT_MAX_STOPS 2 + +/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. + * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ +#define LV_COLOR_MIX_ROUND_OFS 0 + +/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */ +#define LV_OBJ_STYLE_CACHE 0 + +/* Add `id` field to `lv_obj_t` */ +#define LV_USE_OBJ_ID 0 + +/* Automatically assign an ID when obj is created */ +#define LV_OBJ_ID_AUTO_ASSIGN LV_USE_OBJ_ID + +/*Use the builtin obj ID handler functions: +* - lv_obj_assign_id: Called when a widget is created. Use a separate counter for each widget class as an ID. +* - lv_obj_id_compare: Compare the ID to decide if it matches with a requested value. +* - lv_obj_stringify_id: Return e.g. "button3" +* - lv_obj_free_id: Does nothing, as there is no memory allocation for the ID. +* When disabled these functions needs to be implemented by the user.*/ +#define LV_USE_OBJ_ID_BUILTIN 1 + +/*Use obj property set/get API*/ +#define LV_USE_OBJ_PROPERTY 0 + +/*Enable property name support*/ +#define LV_USE_OBJ_PROPERTY_NAME 1 + +/* VG-Lite Simulator */ +/*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ +#define LV_USE_VG_LITE_THORVG 0 + +#if LV_USE_VG_LITE_THORVG + + /*Enable LVGL's blend mode support*/ + #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 + + /*Enable YUV color format support*/ + #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 + + /*Enable Linear gradient extension support*/ + #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + + /*Enable 16 pixels alignment*/ + #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 + + /*Buffer address alignment*/ + #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 + + /*Enable multi-thread render*/ + #define LV_VG_LITE_THORVG_THREAD_RENDER 0 + +#endif + +/*===================== + * COMPILER SETTINGS + *====================*/ + +/*For big endian systems set to 1*/ +#define LV_BIG_ENDIAN_SYSTEM 0 + +/*Define a custom attribute to `lv_tick_inc` function*/ +#define LV_ATTRIBUTE_TICK_INC + +/*Define a custom attribute to `lv_timer_handler` function*/ +#define LV_ATTRIBUTE_TIMER_HANDLER + +/*Define a custom attribute to `lv_display_flush_ready` function*/ +#define LV_ATTRIBUTE_FLUSH_READY + +/*Required alignment size for buffers*/ +#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 + +/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default). + * E.g. __attribute__((aligned(4)))*/ +#define LV_ATTRIBUTE_MEM_ALIGN + +/*Attribute to mark large constant arrays for example font's bitmaps*/ +#define LV_ATTRIBUTE_LARGE_CONST + +/*Compiler prefix for a big array declaration in RAM*/ +#define LV_ATTRIBUTE_LARGE_RAM_ARRAY + +/*Place performance critical functions into a faster memory (e.g RAM)*/ +#define LV_ATTRIBUTE_FAST_MEM + +/*Export integer constant to binding. This macro is used with constants in the form of LV_ that + *should also appear on LVGL binding API such as MicroPython.*/ +#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ + +/*Prefix all global extern data with this*/ +#define LV_ATTRIBUTE_EXTERN_DATA + +/* Use `float` as `lv_value_precise_t` */ +#define LV_USE_FLOAT 0 + +/*================== + * FONT USAGE + *===================*/ + +/*Montserrat fonts with ASCII range and some symbols using bpp = 4 + *https://fonts.google.com/specimen/Montserrat*/ +#define LV_FONT_MONTSERRAT_8 0 +#define LV_FONT_MONTSERRAT_10 0 +#define LV_FONT_MONTSERRAT_12 0 +#define LV_FONT_MONTSERRAT_14 1 +#define LV_FONT_MONTSERRAT_16 0 +#define LV_FONT_MONTSERRAT_18 0 +#define LV_FONT_MONTSERRAT_20 0 +#define LV_FONT_MONTSERRAT_22 0 +#define LV_FONT_MONTSERRAT_24 0 +#define LV_FONT_MONTSERRAT_26 0 +#define LV_FONT_MONTSERRAT_28 0 +#define LV_FONT_MONTSERRAT_30 0 +#define LV_FONT_MONTSERRAT_32 0 +#define LV_FONT_MONTSERRAT_34 0 +#define LV_FONT_MONTSERRAT_36 0 +#define LV_FONT_MONTSERRAT_38 0 +#define LV_FONT_MONTSERRAT_40 0 +#define LV_FONT_MONTSERRAT_42 0 +#define LV_FONT_MONTSERRAT_44 0 +#define LV_FONT_MONTSERRAT_46 0 +#define LV_FONT_MONTSERRAT_48 0 + +/*Demonstrate special features*/ +#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ +#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ +#define LV_FONT_SIMSUN_14_CJK 0 /*1000 most common CJK radicals*/ +#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ + +/*Pixel perfect monospace fonts*/ +#define LV_FONT_UNSCII_8 0 +#define LV_FONT_UNSCII_16 0 + +/*Optionally declare custom fonts here. + *You can use these fonts as default font too and they will be available globally. + *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ +#define LV_FONT_CUSTOM_DECLARE + +/*Always set a default font*/ +#define LV_FONT_DEFAULT &lv_font_montserrat_14 + +/*Enable handling large font and/or fonts with a lot of characters. + *The limit depends on the font size, font face and bpp. + *Compiler error will be triggered if a font needs it.*/ +#define LV_FONT_FMT_TXT_LARGE 0 + +/*Enables/disables support for compressed fonts.*/ +#define LV_USE_FONT_COMPRESSED 0 + +/*Enable drawing placeholders when glyph dsc is not found*/ +#define LV_USE_FONT_PLACEHOLDER 1 + +/*================= + * TEXT SETTINGS + *=================*/ + +/** + * Select a character encoding for strings. + * Your IDE or editor should have the same character encoding + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + */ +#define LV_TXT_ENC LV_TXT_ENC_UTF8 + +/*Can break (wrap) texts on these chars*/ +#define LV_TXT_BREAK_CHARS " ,.;:-_)]}" + +/*If a word is at least this long, will break wherever "prettiest" + *To disable, set to a value <= 0*/ +#define LV_TXT_LINE_BREAK_LONG_LEN 0 + +/*Minimum number of characters in a long word to put on a line before a break. + *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 + +/*Minimum number of characters in a long word to put on a line after a break. + *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + +/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts. + *The direction will be processed according to the Unicode Bidirectional Algorithm: + *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ +#define LV_USE_BIDI 0 +#if LV_USE_BIDI + /*Set the default direction. Supported values: + *`LV_BASE_DIR_LTR` Left-to-Right + *`LV_BASE_DIR_RTL` Right-to-Left + *`LV_BASE_DIR_AUTO` detect texts base direction*/ + #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO +#endif + +/*Enable Arabic/Persian processing + *In these languages characters should be replaced with another form based on their position in the text*/ +#define LV_USE_ARABIC_PERSIAN_CHARS 0 + +/*================== + * WIDGETS + *================*/ + +/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ + +#define LV_WIDGETS_HAS_DEFAULT_VALUE 1 + +#define LV_USE_ANIMIMG 1 + +#define LV_USE_ARC 1 + +#define LV_USE_BAR 1 + +#define LV_USE_BUTTON 1 + +#define LV_USE_BUTTONMATRIX 1 + +#define LV_USE_CALENDAR 1 +#if LV_USE_CALENDAR + #define LV_CALENDAR_WEEK_STARTS_MONDAY 0 + #if LV_CALENDAR_WEEK_STARTS_MONDAY + #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} + #else + #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} + #endif + + #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} + #define LV_USE_CALENDAR_HEADER_ARROW 1 + #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 + #define LV_USE_CALENDAR_CHINESE 0 +#endif /*LV_USE_CALENDAR*/ + +#define LV_USE_CANVAS 1 + +#define LV_USE_CHART 1 + +#define LV_USE_CHECKBOX 1 + +#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ + +#define LV_USE_IMAGE 1 /*Requires: lv_label*/ + +#define LV_USE_IMAGEBUTTON 1 + +#define LV_USE_KEYBOARD 1 + +#define LV_USE_LABEL 1 +#if LV_USE_LABEL + #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ + #define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ + #define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/ +#endif + +#define LV_USE_LED 1 + +#define LV_USE_LINE 1 + +#define LV_USE_LIST 1 + +#define LV_USE_LOTTIE 0 /*Requires: lv_canvas, thorvg */ + +#define LV_USE_MENU 1 + +#define LV_USE_MSGBOX 1 + +#define LV_USE_ROLLER 1 /*Requires: lv_label*/ + +#define LV_USE_SCALE 1 + +#define LV_USE_SLIDER 1 /*Requires: lv_bar*/ + +#define LV_USE_SPAN 1 +#if LV_USE_SPAN + /*A line text can contain maximum num of span descriptor */ + #define LV_SPAN_SNIPPET_STACK_SIZE 64 +#endif + +#define LV_USE_SPINBOX 1 + +#define LV_USE_SPINNER 1 + +#define LV_USE_SWITCH 1 + +#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ +#if LV_USE_TEXTAREA != 0 + #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ +#endif + +#define LV_USE_TABLE 1 + +#define LV_USE_TABVIEW 1 + +#define LV_USE_TILEVIEW 1 + +#define LV_USE_WIN 1 + +/*================== + * THEMES + *==================*/ + +/*A simple, impressive and very complete theme*/ +#define LV_USE_THEME_DEFAULT 1 +#if LV_USE_THEME_DEFAULT + + /*0: Light mode; 1: Dark mode*/ + #define LV_THEME_DEFAULT_DARK 0 + + /*1: Enable grow on press*/ + #define LV_THEME_DEFAULT_GROW 1 + + /*Default transition time in [ms]*/ + #define LV_THEME_DEFAULT_TRANSITION_TIME 80 +#endif /*LV_USE_THEME_DEFAULT*/ + +/*A very simple theme that is a good starting point for a custom theme*/ +#define LV_USE_THEME_SIMPLE 1 + +/*A theme designed for monochrome displays*/ +#define LV_USE_THEME_MONO 1 + +/*================== + * LAYOUTS + *==================*/ + +/*A layout similar to Flexbox in CSS.*/ +#define LV_USE_FLEX 1 + +/*A layout similar to Grid in CSS.*/ +#define LV_USE_GRID 1 + +/*==================== + * 3RD PARTS LIBRARIES + *====================*/ + +/*File system interfaces for common APIs */ + +/*API for fopen, fread, etc*/ +#define LV_USE_FS_STDIO 0 +#if LV_USE_FS_STDIO + #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif + +/*API for open, read, etc*/ +#define LV_USE_FS_POSIX 0 +#if LV_USE_FS_POSIX + #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif + +/*API for CreateFile, ReadFile, etc*/ +#define LV_USE_FS_WIN32 0 +#if LV_USE_FS_WIN32 + #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif + +/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/ +#define LV_USE_FS_FATFS 0 +#if LV_USE_FS_FATFS + #define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif + +/*API for memory-mapped file access. */ +#define LV_USE_FS_MEMFS 0 +#if LV_USE_FS_MEMFS + #define LV_FS_MEMFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ +#endif + +/*API for LittleFs. */ +#define LV_USE_FS_LITTLEFS 0 +#if LV_USE_FS_LITTLEFS + #define LV_FS_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ +#endif + +/*API for Arduino LittleFs. */ +#define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ +#endif + +/*API for Arduino Sd. */ +#define LV_USE_FS_ARDUINO_SD 0 +#if LV_USE_FS_ARDUINO_SD + #define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_ARDUINO_SD_CS_PIN 0 /*Set the pin connected to the chip select line of the SD card */ + #define LV_FS_ARDUINO_SD_FREQUENCY 40000000 /*Set the frequency used by the chip of the SD CARD */ +#endif + +/*LODEPNG decoder library*/ +#define LV_USE_LODEPNG 0 + +/*PNG decoder(libpng) library*/ +#define LV_USE_LIBPNG 0 + +/*BMP decoder library*/ +#define LV_USE_BMP 0 + +/* JPG + split JPG decoder library. + * Split JPG is a custom format optimized for embedded systems. */ +#define LV_USE_TJPGD 0 + +/* libjpeg-turbo decoder library. + * Supports complete JPEG specifications and high-performance JPEG decoding. */ +#define LV_USE_LIBJPEG_TURBO 0 + +/*GIF decoder library*/ +#define LV_USE_GIF 0 +#if LV_USE_GIF +/*GIF decoder accelerate*/ +#define LV_GIF_CACHE_DECODE_DATA 0 +#endif + + +/*Decode bin images to RAM*/ +#define LV_BIN_DECODER_RAM_LOAD 0 + +/*RLE decompress library*/ +#define LV_USE_RLE 0 + +/*QR code library*/ +#define LV_USE_QRCODE 0 + +/*Barcode code library*/ +#define LV_USE_BARCODE 0 + +/*FreeType library*/ +#define LV_USE_FREETYPE 0 +#if LV_USE_FREETYPE + /*Let FreeType to use LVGL memory and file porting*/ + #define LV_FREETYPE_USE_LVGL_PORT 0 + + /*Cache count of the glyphs in FreeType. It means the number of glyphs that can be cached. + *The higher the value, the more memory will be used.*/ + #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 +#endif + +/* Built-in TTF decoder */ +#define LV_USE_TINY_TTF 0 +#if LV_USE_TINY_TTF + /* Enable loading TTF data from files */ + #define LV_TINY_TTF_FILE_SUPPORT 0 + #define LV_TINY_TTF_CACHE_GLYPH_CNT 256 +#endif + +/*Rlottie library*/ +#define LV_USE_RLOTTIE 0 + +/*Enable Vector Graphic APIs*/ +#define LV_USE_VECTOR_GRAPHIC 0 + +/* Enable ThorVG (vector graphics library) from the src/libs folder */ +#define LV_USE_THORVG_INTERNAL 0 + +/* Enable ThorVG by assuming that its installed and linked to the project */ +#define LV_USE_THORVG_EXTERNAL 0 + +/*Use lvgl built-in LZ4 lib*/ +#define LV_USE_LZ4_INTERNAL 0 + +/*Use external LZ4 library*/ +#define LV_USE_LZ4_EXTERNAL 0 + +/*FFmpeg library for image decoding and playing videos + *Supports all major image formats so do not enable other image decoder with it*/ +#define LV_USE_FFMPEG 0 +#if LV_USE_FFMPEG + /*Dump input information to stderr*/ + #define LV_FFMPEG_DUMP_FORMAT 0 +#endif + +/*================== + * OTHERS + *==================*/ + +/*1: Enable API to take snapshot for object*/ +#define LV_USE_SNAPSHOT 0 + +/*1: Enable system monitor component*/ +#define LV_USE_SYSMON 0 +#if LV_USE_SYSMON + /*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/ + #define LV_SYSMON_GET_IDLE lv_timer_get_idle + + /*1: Show CPU usage and FPS count + * Requires `LV_USE_SYSMON = 1`*/ + #define LV_USE_PERF_MONITOR 0 + #if LV_USE_PERF_MONITOR + #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT + + /*0: Displays performance data on the screen, 1: Prints performance data using log.*/ + #define LV_USE_PERF_MONITOR_LOG_MODE 0 + #endif + + /*1: Show the used memory and the memory fragmentation + * Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` + * Requires `LV_USE_SYSMON = 1`*/ + #define LV_USE_MEM_MONITOR 0 + #if LV_USE_MEM_MONITOR + #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT + #endif + +#endif /*LV_USE_SYSMON*/ + +/*1: Enable the runtime performance profiler*/ +#define LV_USE_PROFILER 0 +#if LV_USE_PROFILER + /*1: Enable the built-in profiler*/ + #define LV_USE_PROFILER_BUILTIN 1 + #if LV_USE_PROFILER_BUILTIN + /*Default profiler trace buffer size*/ + #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /*[bytes]*/ + #endif + + /*Header to include for the profiler*/ + #define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" + + /*Profiler start point function*/ + #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN + + /*Profiler end point function*/ + #define LV_PROFILER_END LV_PROFILER_BUILTIN_END + + /*Profiler start point function with custom tag*/ + #define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG + + /*Profiler end point function with custom tag*/ + #define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG +#endif + +/*1: Enable Monkey test*/ +#define LV_USE_MONKEY 0 + +/*1: Enable grid navigation*/ +#define LV_USE_GRIDNAV 0 + +/*1: Enable lv_obj fragment*/ +#define LV_USE_FRAGMENT 0 + +/*1: Support using images as font in label or span widgets */ +#define LV_USE_IMGFONT 0 + +/*1: Enable an observer pattern implementation*/ +#define LV_USE_OBSERVER 1 + +/*1: Enable Pinyin input method*/ +/*Requires: lv_keyboard*/ +#define LV_USE_IME_PINYIN 0 +#if LV_USE_IME_PINYIN + /*1: Use default thesaurus*/ + /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesaurus*/ + #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 + /*Set the maximum number of candidate panels that can be displayed*/ + /*This needs to be adjusted according to the size of the screen*/ + #define LV_IME_PINYIN_CAND_TEXT_NUM 6 + + /*Use 9 key input(k9)*/ + #define LV_IME_PINYIN_USE_K9_MODE 1 + #if LV_IME_PINYIN_USE_K9_MODE == 1 + #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 + #endif /*LV_IME_PINYIN_USE_K9_MODE*/ +#endif + +/*1: Enable file explorer*/ +/*Requires: lv_table*/ +#define LV_USE_FILE_EXPLORER 0 +#if LV_USE_FILE_EXPLORER + /*Maximum length of path*/ + #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) + /*Quick access bar, 1:use, 0:not use*/ + /*Requires: lv_list*/ + #define LV_FILE_EXPLORER_QUICK_ACCESS 1 +#endif + +/*================== + * DEVICES + *==================*/ + +/*Use SDL to open window on PC and handle mouse and keyboard*/ +#define LV_USE_SDL 0 +#if LV_USE_SDL + #define LV_SDL_INCLUDE_PATH + #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/ + #define LV_SDL_BUF_COUNT 1 /*1 or 2*/ + #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/ + #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/ + #define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/ +#endif + +/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/ +#define LV_USE_X11 0 +#if LV_USE_X11 + #define LV_X11_DIRECT_EXIT 1 /*Exit the application when all X11 windows have been closed*/ + #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for rendering*/ + /*select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!)*/ + #define LV_X11_RENDER_MODE_PARTIAL 1 /*Partial render mode (preferred)*/ + #define LV_X11_RENDER_MODE_DIRECT 0 /*direct render mode*/ + #define LV_X11_RENDER_MODE_FULL 0 /*Full render mode*/ +#endif + +/*Driver for /dev/fb*/ +#define LV_USE_LINUX_FBDEV 0 +#if LV_USE_LINUX_FBDEV + #define LV_LINUX_FBDEV_BSD 0 + #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL + #define LV_LINUX_FBDEV_BUFFER_COUNT 0 + #define LV_LINUX_FBDEV_BUFFER_SIZE 60 +#endif + +/*Use Nuttx to open window and handle touchscreen*/ +#define LV_USE_NUTTX 0 + +#if LV_USE_NUTTX + #define LV_USE_NUTTX_LIBUV 0 + + /*Use Nuttx custom init API to open window and handle touchscreen*/ + #define LV_USE_NUTTX_CUSTOM_INIT 0 + + /*Driver for /dev/lcd*/ + #define LV_USE_NUTTX_LCD 0 + #if LV_USE_NUTTX_LCD + #define LV_NUTTX_LCD_BUFFER_COUNT 0 + #define LV_NUTTX_LCD_BUFFER_SIZE 60 + #endif + + /*Driver for /dev/input*/ + #define LV_USE_NUTTX_TOUCHSCREEN 0 + +#endif + +/*Driver for /dev/dri/card*/ +#define LV_USE_LINUX_DRM 0 + +/*Interface for TFT_eSPI*/ +#define LV_USE_TFT_ESPI 0 + +/*Driver for evdev input devices*/ +#define LV_USE_EVDEV 0 + +/*Driver for libinput input devices*/ +#define LV_USE_LIBINPUT 0 + +#if LV_USE_LIBINPUT + #define LV_LIBINPUT_BSD 0 + + /*Full keyboard support*/ + #define LV_LIBINPUT_XKB 0 + #if LV_LIBINPUT_XKB + /*"setxkbmap -query" can help find the right values for your keyboard*/ + #define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL } + #endif +#endif + +/*Drivers for LCD devices connected via SPI/parallel port*/ +#define LV_USE_ST7735 0 +#define LV_USE_ST7789 0 +#define LV_USE_ST7796 0 +#define LV_USE_ILI9341 0 + +#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) + +/*Driver for Renesas GLCD*/ +#define LV_USE_RENESAS_GLCDC 0 + +/* LVGL Windows backend */ +#define LV_USE_WINDOWS 0 + +/* Use OpenGL to open window on PC and handle mouse and keyboard */ +#define LV_USE_OPENGLES 0 +#if LV_USE_OPENGLES + #define LV_USE_OPENGLES_DEBUG 1 /* Enable or disable debug for opengles */ +#endif + +/* QNX Screen display and input drivers */ +#define LV_USE_QNX 1 +#if LV_USE_QNX + #define LV_QNX_BUF_COUNT 2 /*1 or 2*/ +#endif + +/*================== +* EXAMPLES +*==================*/ + +/*Enable the examples to be built with the library*/ +#define LV_BUILD_EXAMPLES 1 + +/*=================== + * DEMO USAGE + ====================*/ + +/*Show some widget. It might be required to increase `LV_MEM_SIZE` */ +#define LV_USE_DEMO_WIDGETS 0 + +/*Demonstrate the usage of encoder and keyboard*/ +#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + +/*Benchmark your system*/ +#define LV_USE_DEMO_BENCHMARK 0 + +/*Render test for each primitives. Requires at least 480x272 display*/ +#define LV_USE_DEMO_RENDER 0 + +/*Stress test for LVGL*/ +#define LV_USE_DEMO_STRESS 0 + +/*Music player demo*/ +#define LV_USE_DEMO_MUSIC 0 +#if LV_USE_DEMO_MUSIC + #define LV_DEMO_MUSIC_SQUARE 0 + #define LV_DEMO_MUSIC_LANDSCAPE 0 + #define LV_DEMO_MUSIC_ROUND 0 + #define LV_DEMO_MUSIC_LARGE 0 + #define LV_DEMO_MUSIC_AUTO_PLAY 0 +#endif + +/*Flex layout demo*/ +#define LV_USE_DEMO_FLEX_LAYOUT 0 + +/*Smart-phone like multi-language demo*/ +#define LV_USE_DEMO_MULTILANG 0 + +/*Widget transformation demo*/ +#define LV_USE_DEMO_TRANSFORM 0 + +/*Demonstrate scroll settings*/ +#define LV_USE_DEMO_SCROLL 0 + +/*Vector graphic demo*/ +#define LV_USE_DEMO_VECTOR_GRAPHIC 0 + +/*--END OF LV_CONF_H--*/ + +#endif /*LV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/env_support/qnx/x86_64/Makefile b/env_support/qnx/x86_64/Makefile new file mode 100644 index 000000000..c95a66648 --- /dev/null +++ b/env_support/qnx/x86_64/Makefile @@ -0,0 +1,2 @@ +LIST=VARIANT +include recurse.mk diff --git a/env_support/qnx/x86_64/a/Makefile b/env_support/qnx/x86_64/a/Makefile new file mode 100644 index 000000000..2c760893e --- /dev/null +++ b/env_support/qnx/x86_64/a/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/env_support/qnx/x86_64/so/Makefile b/env_support/qnx/x86_64/so/Makefile new file mode 100644 index 000000000..2c760893e --- /dev/null +++ b/env_support/qnx/x86_64/so/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/lv_conf_template.h b/lv_conf_template.h index 14a9e3014..5339df811 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1016,6 +1016,12 @@ #define LV_USE_OPENGLES_DEBUG 1 /* Enable or disable debug for opengles */ #endif +/* QNX Screen display and input drivers */ +#define LV_USE_QNX 0 +#if LV_USE_QNX + #define LV_QNX_BUF_COUNT 1 /*1 or 2*/ +#endif + /*================== * EXAMPLES *==================*/ diff --git a/src/drivers/lv_drivers.h b/src/drivers/lv_drivers.h index f7f2e2ac1..675a51f66 100644 --- a/src/drivers/lv_drivers.h +++ b/src/drivers/lv_drivers.h @@ -40,6 +40,8 @@ extern "C" { #include "glfw/lv_glfw_window.h" #include "glfw/lv_glfw_mouse.h" +#include "qnx/lv_qnx.h" + /********************* * DEFINES *********************/ diff --git a/src/drivers/qnx/lv_qnx.c b/src/drivers/qnx/lv_qnx.c new file mode 100644 index 000000000..f31e72710 --- /dev/null +++ b/src/drivers/qnx/lv_qnx.c @@ -0,0 +1,542 @@ +/** + * @file lv_qnx.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_qnx.h" +#if LV_USE_QNX +#include +#include "../../core/lv_refr.h" +#include "../../stdlib/lv_string.h" +#include "../../core/lv_global.h" +#include "../../display/lv_display_private.h" +#include "../../lv_init.h" +#include +#include +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + screen_window_t window; + screen_buffer_t buffers[LV_QNX_BUF_COUNT]; + int bufidx; + bool managed; + lv_indev_t * pointer; + lv_indev_t * keyboard; +} lv_qnx_window_t; + +typedef struct { + int pos[2]; + int buttons; +} lv_qnx_pointer_t; + +typedef struct { + int key; + int flags; +} lv_qnx_keyboard_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static uint32_t get_ticks(void); +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p); +static bool window_create(lv_display_t * disp); +static bool init_display_from_window(lv_display_t * disp); +static void get_pointer(lv_indev_t * indev, lv_indev_data_t * data); +static void get_key(lv_indev_t * indev, lv_indev_data_t * data); +static bool handle_pointer_event(lv_display_t * disp, screen_event_t event); +static bool handle_keyboard_event(lv_display_t * disp, screen_event_t event); +static void release_disp_cb(lv_event_t * e); +static void refresh_cb(lv_timer_t * timer); + +/*********************** + * GLOBAL PROTOTYPES + ***********************/ + +static screen_context_t context; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_qnx_window_create(int32_t hor_res, int32_t ver_res) +{ + static bool inited = false; + + if(!inited) { + if(screen_create_context(&context, + SCREEN_APPLICATION_CONTEXT) != 0) { + LV_LOG_ERROR("screen_create_context: %s", strerror(errno)); + return NULL; + } + + lv_tick_set_cb(get_ticks); + inited = true; + } + + lv_qnx_window_t * dsc = lv_malloc_zeroed(sizeof(lv_qnx_window_t)); + LV_ASSERT_MALLOC(dsc); + if(dsc == NULL) return NULL; + + lv_display_t * disp = lv_display_create(hor_res, ver_res); + if(disp == NULL) { + lv_free(dsc); + return NULL; + } + lv_display_add_event_cb(disp, release_disp_cb, LV_EVENT_DELETE, disp); + lv_display_set_driver_data(disp, dsc); + if(!window_create(disp)) { + lv_free(dsc); + return NULL; + } + + lv_display_set_flush_cb(disp, flush_cb); + + if(!init_display_from_window(disp)) { + screen_destroy_window(dsc->window); + lv_free(dsc); + return NULL; + } + + /*Replace the default refresh timer handler, so that we can run it on + *demand instead of constantly.*/ + lv_timer_t * refr_timer = lv_display_get_refr_timer(disp); + lv_timer_set_cb(refr_timer, refresh_cb); + + return disp; +} + +void lv_qnx_window_set_title(lv_display_t * disp, const char * title) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(!dsc->managed) { + /*Can't set title if there is no window manager*/ + return; + } + + screen_event_t event; + screen_create_event(&event); + + char title_buf[64]; + lv_snprintf(title_buf, sizeof(title_buf), "Title=%s", title); + + int type = SCREEN_EVENT_MANAGER; + screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type); + screen_set_event_property_cv(event, SCREEN_PROPERTY_USER_DATA, + sizeof(title_buf), title_buf); + screen_set_event_property_pv(event, SCREEN_PROPERTY_WINDOW, + (void **)&dsc->window); + screen_set_event_property_pv(event, SCREEN_PROPERTY_CONTEXT, + (void **)&context); + + screen_inject_event(NULL, event); +} + +bool lv_qnx_add_pointer_device(lv_display_t * disp) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->pointer != NULL) { + /*Only one pointer device per display*/ + return false; + } + + lv_qnx_pointer_t * ptr_dsc = lv_malloc_zeroed(sizeof(lv_qnx_pointer_t)); + LV_ASSERT_MALLOC(ptr_dsc); + if(ptr_dsc == NULL) { + return false; + } + + dsc->pointer = lv_indev_create(); + if(dsc->pointer == NULL) { + lv_free(ptr_dsc); + return false; + } + + lv_indev_set_type(dsc->pointer, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(dsc->pointer, get_pointer); + lv_indev_set_driver_data(dsc->pointer, ptr_dsc); + lv_indev_set_mode(dsc->pointer, LV_INDEV_MODE_EVENT); + return true; +} + +bool lv_qnx_add_keyboard_device(lv_display_t * disp) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->keyboard != NULL) { + /*Only one keyboard device per display*/ + return false; + } + + lv_qnx_keyboard_t * kbd_dsc = lv_malloc_zeroed(sizeof(lv_qnx_keyboard_t)); + LV_ASSERT_MALLOC(kbd_dsc); + if(dsc == NULL) { + return false; + } + + dsc->keyboard = lv_indev_create(); + if(dsc->keyboard == NULL) { + lv_free(kbd_dsc); + return false; + } + + lv_indev_set_type(dsc->keyboard, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_read_cb(dsc->keyboard, get_key); + lv_indev_set_driver_data(dsc->keyboard, kbd_dsc); + lv_indev_set_mode(dsc->keyboard, LV_INDEV_MODE_EVENT); + return true; +} + +int lv_qnx_event_loop(lv_display_t * disp) +{ + lv_refr_now(disp); + + /*Run the event loop*/ + screen_event_t event; + if(screen_create_event(&event) != 0) { + LV_LOG_ERROR("screen_create_event: %s", strerror(errno)); + return EXIT_FAILURE; + } + + uint64_t timeout_ns = 0; + for(;;) { + /*Wait for an event, timing out after 16ms if animations are running*/ + if(screen_get_event(context, event, timeout_ns) != 0) { + LV_LOG_ERROR("screen_get_event: %s", strerror(errno)); + return EXIT_FAILURE; + } + + /*Get the event's type*/ + int type; + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(TYPE): %s", strerror(errno)); + return EXIT_FAILURE; + } + + if(type == SCREEN_EVENT_POINTER) { + if(!handle_pointer_event(disp, event)) { + return EXIT_FAILURE; + } + } + else if(type == SCREEN_EVENT_KEYBOARD) { + if(!handle_keyboard_event(disp, event)) { + return EXIT_FAILURE; + } + } + else if(type == SCREEN_EVENT_MANAGER) { + /*Only sub-type supported is closing the window*/ + break; + } + + /*Calculate the next timeout*/ + uint32_t timeout_ms = lv_timer_handler(); + if(timeout_ms == LV_NO_TIMER_READY) { + timeout_ns = -1ULL; + } + else { + timeout_ns = (uint64_t)timeout_ms * 1000000UL; + } + } + + return EXIT_SUCCESS; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static uint32_t get_ticks(void) +{ + uint64_t const ns = clock_gettime_mon_ns(); + return (uint32_t)(ns / 1000000UL); +} + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(screen_post_window(dsc->window, dsc->buffers[dsc->bufidx], 0, NULL, 0) + != 0) { + LV_LOG_ERROR("screen_post_window: %s", strerror(errno)); + } + +#if (LV_QNX_BUF_COUNT > 1) + dsc->bufidx = 1 - dsc->bufidx; +#endif + + lv_display_flush_ready(disp); +} + +static bool window_create(lv_display_t * disp) +{ + /*Create a window*/ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(screen_create_window(&dsc->window, context) != 0) { + LV_LOG_ERROR("screen_create_window: %s", strerror(errno)); + return false; + } + + /*Set window properties*/ + int rect[] = { 0, 0, disp->hor_res, disp->ver_res }; + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_POSITION, + &rect[0]) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(POSITION): %s", strerror(errno)); + return false; + } + + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_SIZE, + &rect[2]) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(SIZE): %s", strerror(errno)); + return false; + } + + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_SOURCE_SIZE, + &rect[2]) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(SOURCE_SIZE): %s", strerror(errno)); + return NULL; + } + + int usage = SCREEN_USAGE_WRITE; + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_USAGE, + &usage) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(USAGE): %s", strerror(errno)); + return NULL; + } + + int format = SCREEN_FORMAT_RGBA8888; + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_FORMAT, + &format) != 0) { + LV_LOG_ERROR("screen_window_set_property_iv(USAGE): %s", strerror(errno)); + return NULL; + } + + /*Initialize window buffers*/ + if(screen_create_window_buffers(dsc->window, LV_QNX_BUF_COUNT) != 0) { + LV_LOG_ERROR("screen_create_window_buffers: %s", strerror(errno)); + return false; + } + + if(screen_get_window_property_pv(dsc->window, SCREEN_PROPERTY_BUFFERS, + (void **)&dsc->buffers) != 0) { + LV_LOG_ERROR("screen_get_window_property_pv(BUFFERS): %s", strerror(errno)); + return false; + } + + /*Connect to the window manager. Can legitimately fail if one is not running*/ + if(screen_manage_window(dsc->window, "Frame=Y") == 0) { + dsc->managed = true; + } + else { + dsc->managed = false; + } + + int visible = 1; + if(screen_set_window_property_iv(dsc->window, SCREEN_PROPERTY_VISIBLE, + &visible) != 0) { + LV_LOG_ERROR("screen_set_window_property_iv(VISIBLE): %s", strerror(errno)); + return false; + } + + return true; +} + +static bool init_display_from_window(lv_display_t * disp) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + + int bufsize; + if(screen_get_buffer_property_iv(dsc->buffers[0], SCREEN_PROPERTY_SIZE, + &bufsize) == -1) { + LV_LOG_ERROR("screen_get_buffer_property_iv(SIZE): %s", strerror(errno)); + return false; + } + + void * ptr1 = NULL; + if(screen_get_buffer_property_pv(dsc->buffers[0], SCREEN_PROPERTY_POINTER, + &ptr1) == -1) { + LV_LOG_ERROR("screen_get_buffer_property_pv(POINTER): %s", strerror(errno)); + return false; + } + + void * ptr2 = NULL; +#if (LV_QNX_BUF_COUNT > 1) + if(screen_get_buffer_property_pv(dsc->buffers[1], SCREEN_PROPERTY_POINTER, + &ptr2) == -1) { + LV_LOG_ERROR("screen_get_buffer_property_pv(POINTER): %s", strerror(errno)); + return false; + } +#endif + + lv_display_set_buffers(disp, ptr1, ptr2, bufsize, LV_DISPLAY_RENDER_MODE_FULL); + return true; +} + +static void release_disp_cb(lv_event_t * e) +{ + lv_display_t * disp = (lv_display_t *) lv_event_get_user_data(e); + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + + if(dsc->window != NULL) { + screen_destroy_window(dsc->window); + } + + if(dsc->pointer != NULL) { + lv_free(dsc->pointer); + } + + if(dsc->keyboard != NULL) { + lv_free(dsc->keyboard); + } + + lv_free(dsc); + lv_display_set_driver_data(disp, NULL); +} + +static void get_pointer(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_qnx_pointer_t * dsc = lv_indev_get_driver_data(indev); + + data->point.x = dsc->pos[0]; + data->point.y = dsc->pos[1]; + if((dsc->buttons & SCREEN_LEFT_MOUSE_BUTTON) != 0) { + data->state = LV_INDEV_STATE_PRESSED; + } + else { + data->state = LV_INDEV_STATE_RELEASED; + } +} + +static bool handle_pointer_event(lv_display_t * disp, screen_event_t event) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->pointer == NULL) return true; + + lv_qnx_pointer_t * ptr_dsc = lv_indev_get_driver_data(dsc->pointer); + + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, + ptr_dsc->pos) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(SOURCE_POSITION): %s", strerror(errno)); + return false; + } + + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, + &ptr_dsc->buttons) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(BUTTONS): %s", strerror(errno)); + return false; + } + + lv_indev_read(dsc->pointer); + return true; +} + +static void get_key(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_qnx_keyboard_t * dsc = lv_indev_get_driver_data(indev); + + if((dsc->flags & KEY_DOWN) != 0) { + data->state = LV_INDEV_STATE_PRESSED; + data->key = dsc->key; + } + else { + data->state = LV_INDEV_STATE_RELEASED; + } +} + +static bool handle_keyboard_event(lv_display_t * disp, screen_event_t event) +{ + lv_qnx_window_t * dsc = lv_display_get_driver_data(disp); + if(dsc->keyboard == NULL) return true; + + lv_qnx_keyboard_t * kbd_dsc = lv_indev_get_driver_data(dsc->keyboard); + + /*Get event data*/ + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_FLAGS, + &kbd_dsc->flags) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(FLAGS): %s", strerror(errno)); + return false; + } + + if(screen_get_event_property_iv(event, SCREEN_PROPERTY_SYM, + &kbd_dsc->key) + != 0) { + LV_LOG_ERROR("screen_get_event_property_iv(SYM): %s", strerror(errno)); + return false; + } + + /*Translate special keys*/ + switch(kbd_dsc->key) { + case KEYCODE_UP: + kbd_dsc->key = LV_KEY_UP; + break; + + case KEYCODE_DOWN: + kbd_dsc->key = LV_KEY_DOWN; + break; + + case KEYCODE_LEFT: + kbd_dsc->key = LV_KEY_LEFT; + break; + + case KEYCODE_RIGHT: + kbd_dsc->key = LV_KEY_RIGHT; + break; + + case KEYCODE_RETURN: + kbd_dsc->key = LV_KEY_ENTER; + break; + + case KEYCODE_BACKSPACE: + kbd_dsc->key = LV_KEY_BACKSPACE; + break; + + case KEYCODE_HOME: + kbd_dsc->key = LV_KEY_HOME; + break; + + case KEYCODE_END: + kbd_dsc->key = LV_KEY_END; + break; + + case KEYCODE_DELETE: + kbd_dsc->key = LV_KEY_DEL; + break; + + default: + /*Ignore other non-ASCII keys, including modifiers*/ + if(kbd_dsc->key > 0xff) return true; + } + + lv_indev_read(dsc->keyboard); + return true; +} + +static void refresh_cb(lv_timer_t * timer) +{ + /*Refresh the window on timeout, but disable the timer. Any callback can + *re-enable it.*/ + lv_display_t * disp = timer->user_data; + lv_refr_now(disp); + lv_timer_pause(timer); +} + +#endif /*LV_USE_QNX*/ diff --git a/src/drivers/qnx/lv_qnx.h b/src/drivers/qnx/lv_qnx.h new file mode 100644 index 000000000..c194d0bdf --- /dev/null +++ b/src/drivers/qnx/lv_qnx.h @@ -0,0 +1,86 @@ +/** + * @file lv_qnx_window.h + * @brief LVGL driver for the QNX Screen compositing window manager + */ + +#ifndef LV_QNX_DISP_H +#define LV_QNX_DISP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" +#include "../../indev/lv_indev.h" + +#if LV_USE_QNX + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a window to use as a display for LVGL. + * @param hor_res The horizontal resolution (size) of the window + * @param ver_res The vertical resolution (size) of the window + * @return A pointer to a new display object if successful, NULL otherwise + */ +lv_display_t * lv_qnx_window_create(int32_t hor_res, int32_t ver_res); + +/** + * Set the title of the window identified by the given display. + * @param disp The display object for the window + * @param title The new title to set + */ +void lv_qnx_window_set_title(lv_display_t * disp, const char * title); + +/** + * Create a pointer input device for the display. + * Only one pointer object is currently supported. + * @param disp The display object associated with the device + * @return true if successful, false otherwise + */ +bool lv_qnx_add_pointer_device(lv_display_t * disp); + +/** + * Create a keyboard input device for the display. + * Only one keyboard object is currently supported. + * @param disp The display object associated with the device + * @return true if successful, false otherwise + */ +bool lv_qnx_add_keyboard_device(lv_display_t * disp); + +/** + * Runs the event loop for the display. + * The function only returns in response to a close event. + * @param disp The display for the event loop + * @return Exit code + */ +int lv_qnx_event_loop(lv_display_t * disp); + +/********************** + * MACROS + **********************/ + +#endif /* LV_DRV_QNX */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_QNX_DISP_H */ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index eea40934c..aa8cfc4a9 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -3367,6 +3367,28 @@ #endif #endif +/* QNX Screen display and input drivers */ +#ifndef LV_USE_QNX + #ifdef CONFIG_LV_USE_QNX + #define LV_USE_QNX CONFIG_LV_USE_QNX + #else + #define LV_USE_QNX 0 + #endif +#endif +#if LV_USE_QNX + #ifndef LV_QNX_BUF_COUNT + #ifdef _LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_QNX_BUF_COUNT + #define LV_QNX_BUF_COUNT CONFIG_LV_QNX_BUF_COUNT + #else + #define LV_QNX_BUF_COUNT 0 + #endif + #else + #define LV_QNX_BUF_COUNT 1 /*1 or 2*/ + #endif + #endif +#endif + /*================== * EXAMPLES *==================*/