{"id":13618263,"url":"https://github.com/lupyuen/pinephone-lvgl-zig","last_synced_at":"2025-04-11T17:40:40.211Z","repository":{"id":87766911,"uuid":"591258562","full_name":"lupyuen/pinephone-lvgl-zig","owner":"lupyuen","description":"LVGL for PinePhone (and WebAssembly) with Zig and Apache NuttX RTOS","archived":false,"fork":false,"pushed_at":"2023-08-10T04:00:34.000Z","size":20408,"stargazers_count":20,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-25T13:39:43.669Z","etag":null,"topics":["lvgl","nuttx","pinephone","wasm","zig"],"latest_commit_sha":null,"homepage":"https://lupyuen.github.io/articles/lvgl4","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lupyuen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":["lupyuen"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["paypal.me/lupyuen"]}},"created_at":"2023-01-20T10:10:24.000Z","updated_at":"2024-09-19T23:57:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"41d5b6fb-32d6-43db-bb9e-3b939cd1121f","html_url":"https://github.com/lupyuen/pinephone-lvgl-zig","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Fpinephone-lvgl-zig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Fpinephone-lvgl-zig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Fpinephone-lvgl-zig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lupyuen%2Fpinephone-lvgl-zig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lupyuen","download_url":"https://codeload.github.com/lupyuen/pinephone-lvgl-zig/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248451346,"owners_count":21105854,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lvgl","nuttx","pinephone","wasm","zig"],"created_at":"2024-08-01T20:01:57.194Z","updated_at":"2025-04-11T17:40:40.192Z","avatar_url":"https://github.com/lupyuen.png","language":"Zig","funding_links":["https://github.com/sponsors/lupyuen","paypal.me/lupyuen"],"categories":["Zig","Multimedia \u0026 Graphics"],"sub_categories":["GUI"],"readme":"![LVGL for PinePhone (and WebAssembly) with Zig and Apache NuttX RTOS](https://lupyuen.github.io/images/lvgl4-title.jpg)\n\n# LVGL for PinePhone (and WebAssembly) with Zig and Apache NuttX RTOS\n\nRead the articles...\n\n-   [\"NuttX RTOS for PinePhone: Feature Phone UI in LVGL, Zig and WebAssembly\"](https://lupyuen.github.io/articles/lvgl4)\n\n-   [\"(Possibly) LVGL in WebAssembly with Zig Compiler\"](https://lupyuen.github.io/articles/lvgl3)\n\n-   [\"NuttX RTOS for PinePhone: Boot to LVGL\"](https://lupyuen.github.io/articles/lvgl2)\n\n-   [\"Build an LVGL Touchscreen App with Zig\"](https://lupyuen.github.io/articles/lvgl)\n\nCan we build an __LVGL App in Zig__ for PinePhone... That will run on Apache NuttX RTOS?\n\nCan we preview a PinePhone App with __Zig, LVGL and WebAssembly__ in a Web Browser? To make the UI Coding a little easier?\n\nLet's find out!\n\n# LVGL Zig App\n\nLet's run this LVGL Zig App on PinePhone...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/c7a33f1fe3af4babaa8bc5502ca2b719ae95c2ca/lvgltest.zig#L55-L89\n\n_How is createWidgetsWrapped called?_\n\n`createWidgetsWrapped` will be called by the LVGL Widget Demo [`lv_demo_widgets`](https://github.com/lvgl/lvgl/blob/v8.3.3/demos/widgets/lv_demo_widgets.c#L96-L198), which we'll replace by this Zig version...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/c7a33f1fe3af4babaa8bc5502ca2b719ae95c2ca/lvgltest.zig#L32-L41\n\n_Where's the Zig Wrapper for LVGL?_\n\nOur Zig Wrapper for LVGL is defined here...\n\n-   [lvgl.zig](https://github.com/lupyuen/pinephone-lvgl-zig/blob/main/lvgl.zig)\n\nWe also have a version of the LVGL Zig Code that doesn't call the Zig Wrapper...\n\n-   [lvgltest.zig](https://github.com/lupyuen/pinephone-lvgl-zig/blob/c7a33f1fe3af4babaa8bc5502ca2b719ae95c2ca/lvgltest.zig#L91-L126)\n\n# Build LVGL Zig App\n\nNuttX Build runs this GCC Command to compile [lv_demo_widgets.c](https://github.com/lvgl/lvgl/blob/v8.3.3/demos/widgets/lv_demo_widgets.c#L96-L198) for PinePhone...\n\n```bash\n$ make --trace\n...\ncd $HOME/PinePhone/wip-nuttx/apps/graphics/lvgl\naarch64-none-elf-gcc\n  -c\n  -fno-common\n  -Wall\n  -Wstrict-prototypes\n  -Wshadow\n  -Wundef\n  -Werror\n  -Os\n  -fno-strict-aliasing\n  -fomit-frame-pointer\n  -g\n  -march=armv8-a\n  -mtune=cortex-a53\n  -isystem $HOME/PinePhone/wip-nuttx/nuttx/include\n  -D__NuttX__ \n  -pipe\n  -I $HOME/PinePhone/wip-nuttx/apps/graphics/lvgl\n  -I \"$HOME/PinePhone/wip-nuttx/apps/include\"\n  -Wno-format\n  -Wno-unused-variable\n  \"-I./lvgl/src/core\"\n  \"-I./lvgl/src/draw\"\n  \"-I./lvgl/src/draw/arm2d\"\n  \"-I./lvgl/src/draw/nxp\"\n  \"-I./lvgl/src/draw/nxp/pxp\"\n  \"-I./lvgl/src/draw/nxp/vglite\"\n  \"-I./lvgl/src/draw/sdl\"\n  \"-I./lvgl/src/draw/stm32_dma2d\"\n  \"-I./lvgl/src/draw/sw\"\n  \"-I./lvgl/src/draw/swm341_dma2d\"\n  \"-I./lvgl/src/font\"\n  \"-I./lvgl/src/hal\"\n  \"-I./lvgl/src/misc\"\n  \"-I./lvgl/src/widgets\"\n  \"-DLV_ASSERT_HANDLER=ASSERT(0);\"   \n  lvgl/demos/widgets/lv_demo_widgets.c\n  -o  lvgl/demos/widgets/lv_demo_widgets.c.Users.Luppy.PinePhone.wip-nuttx.apps.graphics.lvgl.o\n```\n\nWe'll copy the above GCC Options to the Zig Compiler and build this Zig Program for PinePhone...\n\n-   [lvgltest.zig](https://github.com/lupyuen/pinephone-lvgl-zig/blob/main/lvgltest.zig)\n\nHere's the Shell Script...\n\n```bash\n## Build the LVGL Zig App\nfunction build_zig {\n\n  ## Go to LVGL Zig Folder\n  pushd ../pinephone-lvgl-zig\n  git pull\n\n  ## Check that NuttX Build has completed and `lv_demo_widgets.*.o` exists\n  if [ ! -f ../apps/graphics/lvgl/lvgl/demos/widgets/lv_demo_widgets.*.o ] \n  then\n    echo \"*** Error: Build NuttX first before building Zig app\"\n    exit 1\n  fi\n\n  ## Compile the Zig App for PinePhone \n  ## (armv8-a with cortex-a53)\n  ## TODO: Change \"..\" to your NuttX Project Directory\n  zig build-obj \\\n    --verbose-cimport \\\n    -target aarch64-freestanding-none \\\n    -mcpu cortex_a53 \\\n    -isystem \"../nuttx/include\" \\\n    -I \"../apps/include\" \\\n    -I \"../apps/graphics/lvgl\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/core\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/arm2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp/pxp\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp/vglite\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/sdl\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/stm32_dma2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/sw\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/swm341_dma2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/font\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/hal\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/misc\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/widgets\" \\\n    lvgltest.zig\n\n  ## Copy the compiled app to NuttX and overwrite `lv_demo_widgets.*.o`\n  ## TODO: Change \"..\" to your NuttX Project Directory\n  cp lvgltest.o \\\n    ../apps/graphics/lvgl/lvgl/demos/widgets/lv_demo_widgets.*.o\n\n  ## Return to NuttX Folder\n  popd\n}\n\n## Download the LVGL Zig App\ngit clone https://github.com/lupyuen/pinephone-lvgl-zig\n\n## Build NuttX for PinePhone\ncd nuttx\nmake -j\n\n## Build the LVGL Zig App\nbuild_zig\n\n## Link the LVGL Zig App with NuttX\nmake -j\n```\n\n[(Original Build Script)](https://gist.github.com/lupyuen/aa1f5c0c45e6029b10e5e2f955d8386c)\n\n[(Updated Build Script)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/2e1c97e49e51b1cbbe0964a9512eba141d0dd09f/build.sh#L192-L223)\n\n[(NuttX Build Files)](https://github.com/lupyuen/pinephone-lvgl-zig/releases/tag/nuttx-build-files)\n\nAnd our LVGL Zig App runs OK on PinePhone!\n\n![LVGL for PinePhone with Zig and Apache NuttX RTOS](https://lupyuen.github.io/images/lvgl2-zig.jpg)\n\n# Simulate PinePhone UI with Zig, LVGL and WebAssembly\n\nRead the article...\n\n-   [\"(Possibly) LVGL in WebAssembly with Zig Compiler\"](https://lupyuen.github.io/articles/lvgl3)\n\nWe're now building a __Feature Phone UI__ for NuttX on PinePhone...\n\nCan we simulate the Feature Phone UI with __Zig, LVGL and WebAssembly__ in a Web Browser? To make the UI Coding a little easier?\n\nWe have previously created a simple __LVGL App with Zig__ for PinePhone...\n\n- [pinephone-lvgl-zig](https://github.com/lupyuen/pinephone-lvgl-zig)\n\nZig natively supports __WebAssembly__...\n\n- [WebAssembly on Zig](https://ziglang.org/documentation/master/#WebAssembly)\n\nSo we might run __Zig + JavaScript__ in a Web Browser like so...\n\n- [WebAssembly With Zig in a Web Browser](https://dev.to/sleibrock/webassembly-with-zig-pt-ii-ei7)\n\nBut LVGL doesn't work with JavaScript yet. LVGL runs in a Web Browser by compiling with Emscripten and SDL...\n\n- [LVGL with Emscripten and SDL](https://github.com/lvgl/lv_web_emscripten)\n\nTherefore we shall do this...\n\n1.  Use Zig to compile LVGL from C to WebAssembly [(With `zig cc`)](https://github.com/lupyuen/zig-bl602-nuttx#zig-compiler-as-drop-in-replacement-for-gcc)\n\n1.  Use Zig to connect the JavaScript UI (canvas rendering + input events) to LVGL WebAssembly [(Like this)](https://dev.to/sleibrock/webassembly-with-zig-pt-ii-ei7)\n\n# WebAssembly Demo with Zig and JavaScript\n\nWe can run __Zig (WebAssembly) + JavaScript__ in a Web Browser like so...\n\n- [WebAssembly With Zig in a Web Browser](https://dev.to/sleibrock/webassembly-with-zig-pt-ii-ei7)\n\nLet's run a simple demo...\n\n- [demo/mandelbrot.zig](demo/mandelbrot.zig): Zig Program that compiles to WebAssembly\n\n- [demo/game.js](demo/game.js): JavaScript that loads the Zig WebAssembly\n\n- [demo/demo.html](demo/demo.html): HTML that calls the JavaScript\n\nTo compile Zig to WebAssembly...\n\n```bash\ngit clone --recursive https://github.com/lupyuen/pinephone-lvgl-zig\ncd pinephone-lvgl-zig\ncd demo\nzig build-lib \\\n  mandelbrot.zig \\\n  -target wasm32-freestanding \\\n  -dynamic \\\n  -rdynamic\n```\n\n[(According to this)](https://ziglang.org/documentation/master/#Freestanding)\n\nThis produces the Compiled WebAssembly [`mandelbrot.wasm`](mandelbrot.wasm).\n\nStart a Local Web Server. [(Like Web Server for Chrome)](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb)\n\nBrowse to `demo/demo.html`. We should see the Mandelbrot Set yay!\n\n![Mandelbrot Set rendered with Zig and WebAssembly](https://lupyuen.github.io/images/zig-wasm.png)\n\n# Import JavaScript Functions into Zig\n\n_How do we import JavaScript Functions into our Zig Program?_\n\nThis is documented here...\n\n- [WebAssembly on Zig](https://ziglang.org/documentation/master/#WebAssembly)\n\nIn our Zig Program, this is how we import and call a JavaScript Function: [demo/mandelbrot.zig](demo/mandelbrot.zig)\n\n```zig\n/// Import `print` Function from JavaScript\nextern fn print(i32) void;\n...\n// Test printing to JavaScript Console.\n// Warning: This is slow!\nif (iterations == 1) { print(iterations); }\n```\n\nWe define the JavaScript Function `print` when loading the WebAssembly Module in our JavaScript: [demo/game.js](demo/game.js)\n\n```javascript\n// Export JavaScript Functions to Zig\nlet importObject = {\n    // JavaScript Environment exported to Zig\n    env: {\n        // JavaScript Print Function exported to Zig\n        print: function(x) { console.log(x); }\n    }\n};\n\n// Load the WebAssembly Module\n// https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/instantiateStreaming\nasync function bootstrap() {\n\n    // Store references to WebAssembly Functions and Memory exported by Zig\n    Game = await WebAssembly.instantiateStreaming(\n        fetch(\"mandelbrot.wasm\"),\n        importObject\n    );\n\n    // Start the Main Function\n    main();\n}\n\n// Start the loading of WebAssembly Module\nbootstrap();\n```\n\n_Will this work for passing Strings and Buffers as parameters?_\n\nNope, the parameter will be passed as a number. (Probably a WebAssembly Data Address)\n\nTo pass Strings and Buffers between JavaScript and Zig, see [daneelsan/zig-wasm-logger](https://github.com/daneelsan/zig-wasm-logger).\n\n# Compile Zig LVGL App to WebAssembly\n\n_Does our Zig LVGL App lvgltest.zig compile to WebAssembly?_\n\nLet's take the earlier steps to compile our Zig LVGL App `lvgltest.zig`. To compile for WebAssembly, we change...\n\n- `zig build-obj` to `zig build-lib`\n\n- Target becomes `-target wasm32-freestanding`\n\n- Remove `-mcpu`\n\n- Add `-dynamic` and `-rdynamic`\n\nLike this...\n\n```bash\n  ## Compile the Zig App for WebAssembly \n  ## TODO: Change \"..\" to your NuttX Project Directory\n  zig build-lib \\\n    --verbose-cimport \\\n    -target wasm32-freestanding \\\n    -dynamic \\\n    -rdynamic \\\n    -isystem \"../nuttx/include\" \\\n    -I \"../apps/include\" \\\n    -I \"../apps/graphics/lvgl\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/core\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/arm2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp/pxp\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp/vglite\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/sdl\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/stm32_dma2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/sw\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/swm341_dma2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/font\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/hal\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/misc\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/widgets\" \\\n    lvgltest.zig\n```\n\n[(According to this)](https://ziglang.org/documentation/master/#Freestanding)\n\n[(NuttX Build Files)](https://github.com/lupyuen/pinephone-lvgl-zig/releases/tag/nuttx-build-files)\n\nOK no errors, this produces the Compiled WebAssembly `lvgltest.wasm`.\n\nNow we tweak [`lvgltest.zig`](lvgltest.zig) for WebAssembly, and call it [`lvglwasm.zig`](lvglwasm.zig)...\n\n```bash\n  ## Compile the Zig App for WebAssembly \n  ## TODO: Change \"..\" to your NuttX Project Directory\n  zig build-lib \\\n    --verbose-cimport \\\n    -target wasm32-freestanding \\\n    -dynamic \\\n    -rdynamic \\\n    -isystem \"../nuttx/include\" \\\n    -I \"../apps/include\" \\\n    -I \"../apps/graphics/lvgl\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/core\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/arm2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp/pxp\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp/vglite\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/sdl\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/stm32_dma2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/sw\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/swm341_dma2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/font\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/hal\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/misc\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/widgets\" \\\n    lvglwasm.zig\n```\n\n[(According to this)](https://ziglang.org/documentation/master/#Freestanding)\n\n[(NuttX Build Files)](https://github.com/lupyuen/pinephone-lvgl-zig/releases/tag/nuttx-build-files)\n\n(We removed our Custom Panic Handler, the default one works fine for WebAssembly)\n\nThis produces the Compiled WebAssembly [`lvglwasm.wasm`](lvglwasm.wasm).\n\nStart a Local Web Server. [(Like Web Server for Chrome)](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb)\n\nBrowse to our HTML [`lvglwasm.html`](lvglwasm.html). Which calls our JavaScript [`lvglwasm.js`](lvglwasm.js) to load the Compiled WebAssembly.\n\nOur JavaScript [`lvglwasm.js`](lvglwasm.js) calls the Zig Function `lv_demo_widgets` that's exported to WebAssembly by our Zig App [`lvglwasm.zig`](lvglwasm.zig).\n\nBut the WebAssembly won't load because we haven't fixed the WebAssembly Imports...\n\n# Fix WebAssembly Imports\n\n_What happens if we don't fix the WebAssembly Imports in our Zig Program?_\n\nSuppose we forgot to import `puts()`. JavaScript Console will show this error when the Web Browser loads our Zig WebAssembly...\n\n```text\nUncaught (in promise) LinkError:\nWebAssembly.instantiate():\nImport #0 module=\"env\" function=\"puts\" error:\nfunction import requires a callable\n```\n\n_But we haven't compiled the LVGL Library to WebAssembly!_\n\nYep that's why LVGL Functions like `lv_label_create` are failing when the Web Browser loads our Zig WebAssembly...\n\n```text\nUncaught (in promise) LinkError:\nWebAssembly.instantiate():\nImport #1 module=\"env\" function=\"lv_label_create\" error:\nfunction import requires a callable\n```\n\nWe need to compile the LVGL Library with `zig cc` and link it in...\n\n# Compile LVGL to WebAssembly with Zig Compiler\n\n_How to compile LVGL from C to WebAssembly with Zig Compiler?_\n\nWe'll use [`zig cc`](https://github.com/lupyuen/zig-bl602-nuttx#zig-compiler-as-drop-in-replacement-for-gcc), since Zig can compile C programs to WebAssembly.\n\nIn the previous section, we're missing the LVGL Function `lv_label_create` in our Zig WebAssembly Module.\n\n`lv_label_create` is defined in this file...\n\n```text\napps/lvgl/src/widgets/lv_label.c\n```\n\nAccording to `make --trace`, `lv_label.c` is compiled with...\n\n```bash\n## Compile LVGL in C\n## TODO: Change \"../../..\" to your NuttX Project Directory\ncd apps/graphics/lvgl\naarch64-none-elf-gcc \\\n  -c \\\n  -fno-common \\\n  -Wall \\\n  -Wstrict-prototypes \\\n  -Wshadow \\\n  -Wundef \\\n  -Werror \\\n  -Os \\\n  -fno-strict-aliasing \\\n  -fomit-frame-pointer \\\n  -ffunction-sections \\\n  -fdata-sections \\\n  -g \\\n  -march=armv8-a \\\n  -mtune=cortex-a53 \\\n  -isystem ../../../nuttx/include \\\n  -D__NuttX__  \\\n  -pipe \\\n  -I ../../../apps/graphics/lvgl \\\n  -I \"../../../apps/include\" \\\n  -Wno-format \\\n  -Wno-format-security \\\n  -Wno-unused-variable \\\n  \"-I./lvgl/src/core\" \\\n  \"-I./lvgl/src/draw\" \\\n  \"-I./lvgl/src/draw/arm2d\" \\\n  \"-I./lvgl/src/draw/nxp\" \\\n  \"-I./lvgl/src/draw/nxp/pxp\" \\\n  \"-I./lvgl/src/draw/nxp/vglite\" \\\n  \"-I./lvgl/src/draw/sdl\" \\\n  \"-I./lvgl/src/draw/stm32_dma2d\" \\\n  \"-I./lvgl/src/draw/sw\" \\\n  \"-I./lvgl/src/draw/swm341_dma2d\" \\\n  \"-I./lvgl/src/font\" \\\n  \"-I./lvgl/src/hal\" \\\n  \"-I./lvgl/src/misc\" \\\n  \"-I./lvgl/src/widgets\" \\\n  \"-DLV_ASSERT_HANDLER=ASSERT(0);\" \\\n  ./lvgl/src/widgets/lv_label.c \\\n  -o  lv_label.c.Users.Luppy.PinePhone.wip-nuttx.apps.graphics.lvgl.o\n```\n\nLet's use the Zig Compiler to compile `lv_label.c` from C to WebAssembly....\n\n- Change `aarch64-none-elf-gcc` to `zig cc`\n\n- Remove `-march`, `-mtune`\n\n- Add the target `-target wasm32-freestanding`\n\n- Add `-dynamic` and `-rdynamic`\n\n- Add `-lc` (because we're calling C Standard Library)\n\n- Add `-DFAR=` (because we won't need Far Pointers)\n\n- Add `-DLV_MEM_CUSTOM=1` (because we're using `malloc` instead of LVGL's TLSF Allocator)\n\n- Set the Default Font to Montserrat 20...\n\n  ```text\n  -DLV_FONT_MONTSERRAT_14=1 \\\n  -DLV_FONT_MONTSERRAT_20=1 \\\n  -DLV_FONT_DEFAULT_MONTSERRAT_20=1 \\\n  -DLV_USE_FONT_PLACEHOLDER=1 \\\n  ```\n\n- Add `-DLV_USE_LOG=1` (to enable logging)\n\n- Add `-DLV_LOG_LEVEL=LV_LOG_LEVEL_TRACE` (for detailed logging)\n\n- For extra logging...\n\n  ```text\n  -DLV_LOG_TRACE_OBJ_CREATE=1 \\\n  -DLV_LOG_TRACE_TIMER=1 \\\n  -DLV_LOG_TRACE_MEM=1 \\\n  ```\n\n- Change `\"-DLV_ASSERT_HANDLER...\"` to...\n\n  ```text\n  \"-DLV_ASSERT_HANDLER={void lv_assert_handler(void); lv_assert_handler();}\"\n  ```\n\n  [(To handle Assertion Failures ourselves)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/bee0e8d8ab9eae3a8c7cea6c64cc7896a5678f53/lvglwasm.zig#L170-L190)\n\n- Change the output to...\n\n  ```text\n  -o ../../../pinephone-lvgl-zig/lv_label.o`\n  ```\n\nLike this...\n\n```bash\n## Compile LVGL from C to WebAssembly\n## TODO: Change \"../../..\" to your NuttX Project Directory\ncd apps/graphics/lvgl\nzig cc \\\n  -target wasm32-freestanding \\\n  -dynamic \\\n  -rdynamic \\\n  -lc \\\n  -DFAR= \\\n  -DLV_MEM_CUSTOM=1 \\\n  -DLV_FONT_MONTSERRAT_14=1 \\\n  -DLV_FONT_MONTSERRAT_20=1 \\\n  -DLV_FONT_DEFAULT_MONTSERRAT_20=1 \\\n  -DLV_USE_FONT_PLACEHOLDER=1 \\\n  -DLV_USE_LOG=1 \\\n  -DLV_LOG_LEVEL=LV_LOG_LEVEL_TRACE \\\n  -DLV_LOG_TRACE_OBJ_CREATE=1 \\\n  -DLV_LOG_TRACE_TIMER=1 \\\n  -DLV_LOG_TRACE_MEM=1 \\\n  \"-DLV_ASSERT_HANDLER={void lv_assert_handler(void); lv_assert_handler();}\" \\\n  -c \\\n  -fno-common \\\n  -Wall \\\n  -Wstrict-prototypes \\\n  -Wshadow \\\n  -Wundef \\\n  -Werror \\\n  -Os \\\n  -fno-strict-aliasing \\\n  -fomit-frame-pointer \\\n  -ffunction-sections \\\n  -fdata-sections \\\n  -g \\\n  -isystem ../../../nuttx/include \\\n  -D__NuttX__  \\\n  -pipe \\\n  -I ../../../apps/graphics/lvgl \\\n  -I \"../../../apps/include\" \\\n  -Wno-format \\\n  -Wno-format-security \\\n  -Wno-unused-variable \\\n  \"-I./lvgl/src/core\" \\\n  \"-I./lvgl/src/draw\" \\\n  \"-I./lvgl/src/draw/arm2d\" \\\n  \"-I./lvgl/src/draw/nxp\" \\\n  \"-I./lvgl/src/draw/nxp/pxp\" \\\n  \"-I./lvgl/src/draw/nxp/vglite\" \\\n  \"-I./lvgl/src/draw/sdl\" \\\n  \"-I./lvgl/src/draw/stm32_dma2d\" \\\n  \"-I./lvgl/src/draw/sw\" \\\n  \"-I./lvgl/src/draw/swm341_dma2d\" \\\n  \"-I./lvgl/src/font\" \\\n  \"-I./lvgl/src/hal\" \\\n  \"-I./lvgl/src/misc\" \\\n  \"-I./lvgl/src/widgets\" \\\n  ./lvgl/src/widgets/lv_label.c \\\n  -o ../../../pinephone-lvgl-zig/lv_label.o\n```\n\n[(NuttX Build Files)](https://github.com/lupyuen/pinephone-lvgl-zig/releases/tag/nuttx-build-files)\n\nThis produces the Compiled WebAssembly `lv_label.o`.\n\n_Will Zig Compiler let us link `lv_label.o` with our Zig LVGL App?_\n\nLet's ask Zig Compiler to link `lv_label.o` with our Zig LVGL App [`lvglwasm.zig`](lvglwasm.zig)...\n\n```bash\n  ## Compile the Zig App for WebAssembly \n  ## TODO: Change \"..\" to your NuttX Project Directory\n  zig build-lib \\\n    --verbose-cimport \\\n    -target wasm32-freestanding \\\n    -dynamic \\\n    -rdynamic \\\n    -lc \\\n    -DFAR= \\\n    -DLV_MEM_CUSTOM=1 \\\n    -DLV_FONT_MONTSERRAT_14=1 \\\n    -DLV_FONT_MONTSERRAT_20=1 \\\n    -DLV_FONT_DEFAULT_MONTSERRAT_20=1 \\\n    -DLV_USE_FONT_PLACEHOLDER=1 \\\n    -DLV_USE_LOG=1 \\\n    -DLV_LOG_LEVEL=LV_LOG_LEVEL_TRACE \\\n    -DLV_LOG_TRACE_OBJ_CREATE=1 \\\n    -DLV_LOG_TRACE_TIMER=1 \\\n    -DLV_LOG_TRACE_MEM=1 \\\n    \"-DLV_ASSERT_HANDLER={void lv_assert_handler(void); lv_assert_handler();}\" \\\n    -I . \\\n    -isystem \"../nuttx/include\" \\\n    -I \"../apps/include\" \\\n    -I \"../apps/graphics/lvgl\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/core\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/arm2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp/pxp\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/nxp/vglite\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/sdl\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/stm32_dma2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/sw\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/draw/swm341_dma2d\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/font\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/hal\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/misc\" \\\n    -I \"../apps/graphics/lvgl/lvgl/src/widgets\" \\\n    lvglwasm.zig \\\n    lv_label.o\n```\n\n[(Source)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/2e1c97e49e51b1cbbe0964a9512eba141d0dd09f/build.sh#L87-L191)\n\n[(NuttX Build Files)](https://github.com/lupyuen/pinephone-lvgl-zig/releases/tag/nuttx-build-files)\n\nNow we see this error in the Web Browser...\n\n```text\nUncaught (in promise) LinkError: \nWebAssembly.instantiate(): \nImport #0 module=\"env\" function=\"lv_obj_clear_flag\" error:\nfunction import requires a callable\n```\n\n`lv_label_create` is no longer missing, because Zig Compiler has linked `lv_label.o` into our Zig LVGL App.\n\nYep Zig Compiler will happily link WebAssembly Object Files with our Zig App yay!\n\nNow we need to compile `lv_obj_clear_flag` and the other LVGL Files from C to WebAssembly with Zig Compiler...\n\n# Compile Entire LVGL Library to WebAssembly\n\nWhen we track down `lv_obj_clear_flag` and the other Missing Functions (by sheer tenacity), we get this trail of LVGL Source Files that need to be compiled from C to WebAssembly...\n\n```text\nwidgets/lv_label.c\ncore/lv_obj.c\nmisc/lv_mem.c\ncore/lv_event.c\ncore/lv_obj_style.c\ncore/lv_obj_pos.c\nmisc/lv_txt.c\ndraw/lv_draw_label.c\ncore/lv_obj_draw.c\nmisc/lv_area.c\ncore/lv_obj_scroll.c\nfont/lv_font.c\ncore/lv_obj_class.c\n(And many more)\n```\n\n[(Based on LVGL 8.3.3)](https://github.com/lvgl/lvgl/tree/v8.3.3)\n\nSo we wrote a script to compile the above LVGL Source Files from C to WebAssembly with `zig cc`...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/2e1c97e49e51b1cbbe0964a9512eba141d0dd09f/build.sh#L7-L191\n\nWhich calls `compile_lvgl` to compile a single LVGL Source File from C to WebAssembly with `zig cc`...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/2e1c97e49e51b1cbbe0964a9512eba141d0dd09f/build.sh#L226-L288\n\n_What happens after we compile the whole bunch of LVGL Source Files from C to WebAssembly?_\n\nNow the Web Browser says that `strlen` is missing...\n\n```text\nUncaught (in promise) LinkError: \nWebAssembly.instantiate(): \nImport #0 module=\"env\" function=\"strlen\" error: \nfunction import requires a callable\n```\n\nLet's fix `strlen`...\n\n_Is it really OK to compile only the necessary LVGL Source Files? Instead of compiling ALL the LVGL Source Files?_\n\nBe careful! We might miss out some symbols. Zig Compiler happily assumes that they are at WebAssembly Address 0...\n\n- [\"LVGL Screen Not Found\"](https://github.com/lupyuen/pinephone-lvgl-zig#lvgl-screen-not-found)\n\nAnd remember to compile the LVGL Fonts!\n\n- [\"LVGL Fonts\"](https://github.com/lupyuen/pinephone-lvgl-zig#lvgl-fonts)\n\nTODO: Disassemble the Compiled WebAssembly and look for other Undefined Variables at WebAssembly Address 0\n\n# C Standard Library is Missing\n\n_strlen is missing from our Zig WebAssembly..._\n\n_But strlen should come from the C Standard Library! (musl)_\n\nNot sure why `strlen` is missing, but we fixed it temporarily by copying from the Zig Library Source Code...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/e99593df6b46ced52f3f8ed644b9c6e455a9d682/lvglwasm.zig#L213-L265\n\nThis seems to be the [same problem mentioned here](https://github.com/andrewrk/lua-in-the-browser#status).\n\n[(Referenced by this pull request)](https://github.com/ziglang/zig/pull/2512)\n\n[(And this issue)](https://github.com/ziglang/zig/issues/5854)\n\nTODO: Maybe because we didn't export `strlen` in our Main Program `lvglwasm.zig`?\n\nTODO: Do we compile C Standard Library ourselves? From musl? Newlib? [wasi-libc](https://github.com/WebAssembly/wasi-libc)?\n\n_What if we change the target to `wasm32-freestanding-musl`?_\n\nNope doesn't help, same problem.\n\n_What if we use `zig build-exe` instead of `zig build-lib`?_\n\nSorry `zig build-exe` is meant for building WASI Executables. [(See this)](https://www.fermyon.com/wasm-languages/c-lang)\n\n`zig build-exe` is not supposed to work for WebAssembly in the Web Browser. [(See this)](https://github.com/ziglang/zig/issues/1570#issuecomment-426370371)\n\n# LVGL Porting Layer for WebAssembly\n\nLVGL expects us to provide a `millis` function that returns the number of elapsed milliseconds...\n\n```text\nUncaught (in promise) LinkError: \nWebAssembly.instantiate(): \nImport #0 module=\"env\" function=\"millis\" error: \nfunction import requires a callable\n```\n\nWe implement `millis` ourselves for WebAssembly...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/bee0e8d8ab9eae3a8c7cea6c64cc7896a5678f53/lvglwasm.zig#L170-L190\n\nTODO: Fix `millis`. How would it work in WebAssembly? Using a counter?\n\nIn the code above, we defined `lv_assert_handler` and `custom_logger` to handle Assertions and Logging in LVGL.\n\nLet's talk about LVGL Logging...\n\n# WebAssembly Logger for LVGL\n\nLet's trace the LVGL Execution with a WebAssembly Logger.\n\n(Remember: `printf` won't work in WebAssembly)\n\nWe set the Custom Logger for LVGL, so that we can print Log Messages to the JavaScript Console...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/f9dc7e1afba2f876c8397d753a79a9cb40b90b75/lvglwasm.zig#L32-L43\n\nThe Custom Logger is defined in our Zig Program...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/f9dc7e1afba2f876c8397d753a79a9cb40b90b75/lvglwasm.zig#L149-L152\n\n`wasmlog` is our Zig Logger for WebAssembly: [wasmlog.zig](wasmlog.zig)\n\n(Based on [daneelsan/zig-wasm-logger](https://github.com/daneelsan/zig-wasm-logger))\n\n`jsConsoleLogWrite` and `jsConsoleLogFlush` are defined in our JavaScript...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/1ed4940d505e263727a36c362da54388be4cbca0/lvglwasm.js#L55-L66\n\n`wasm.getString` also comes from our JavaScript...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/1ed4940d505e263727a36c362da54388be4cbca0/lvglwasm.js#L10-L27\n\nNow we can see the LVGL Log Messages in the JavaScript Console yay! (Pic below)\n\n```text\ncustom_logger: [Warn]\t(0.001, +1)\nlv_disp_get_scr_act:\nno display registered to get its active screen\n(in lv_disp.c line #54)\n```\n\nLet's initialise the LVGL Display...\n\n![WebAssembly Logger for LVGL](https://lupyuen.github.io/images/zig-wasm2.png)\n\n# Initialise LVGL Display\n\nAccording to the LVGL Docs, this is how we initialise and operate LVGL...\n\n1.  Call `lv_init()`\n\n1.  Register the LVGL Display and LVGL Input Devices\n\n1.  Call `lv_tick_inc(x)` every x milliseconds in an interrupt to report the elapsed time to LVGL\n\n    (Not required, because LVGL calls `millis` to fetch the elapsed time)\n\n1.  Call `lv_timer_handler()` every few milliseconds to handle LVGL related tasks\n\n[(Source)](https://docs.lvgl.io/8.3/porting/project.html#initialization)\n\nTo register the LVGL Display, we should do this...\n\n- [Create LVGL Draw Buffer](https://docs.lvgl.io/8.3/porting/display.html#draw-buffer)\n\n- [Register LVGL Display](https://docs.lvgl.io/8.3/porting/display.html#examples)\n\nBut we can't do this in Zig...\n\n```zig\n// Nope! lv_disp_drv_t is an Opaque Type\nvar disp_drv = c.lv_disp_drv_t{};\nc.lv_disp_drv_init(\u0026disp_drv);\n```\n\nBecause `lv_disp_drv_t` is an Opaque Type.\n\n[(`lv_disp_drv_t` contains Bit Fields, hence it's Opaque)](https://lupyuen.github.io/articles/lvgl#appendix-zig-opaque-types)\n\nThus we apply this workaround to create `lv_disp_drv_t` in C...\n\n- [\"Fix Opaque Types\"](https://lupyuen.github.io/articles/lvgl#fix-opaque-types)\n\nAnd we get this LVGL Display Interface for Zig: [display.c](display.c)\n\nFinally this is how we initialise the LVGL Display in Zig WebAssembly...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/d584f43c6354f12bdc15bdb8632cdd3f6f5dc7ff/lvglwasm.zig#L38-L84\n\nNow we handle LVGL Tasks...\n\n# Handle LVGL Tasks\n\nEarlier we talked about __handling LVGL Tasks__...\n\n1.  Call __lv_tick_inc(x)__ every __x__ milliseconds (in an Interrupt) to report the __Elapsed Time__ to LVGL\n\n    [(Not required, because LVGL calls __millis__ to fetch the Elapsed Time)](https://lupyuen.github.io/articles/lvgl3#lvgl-porting-layer-for-webassembly)\n\n1.  Call __lv_timer_handler__ every few milliseconds to handle __LVGL Tasks__\n\n[(From the __LVGL Docs__)](https://docs.lvgl.io/8.3/porting/project.html#initialization)\n\nThis is how we call __lv_timer_handler__ in Zig: [lvglwasm.zig](https://github.com/lupyuen/pinephone-lvgl-zig/blob/main/lvglwasm.zig#L69-L85)\n\n```zig\n/// Main Function for our Zig LVGL App\npub export fn lv_demo_widgets() void {\n\n  // Omitted: Init LVGL Display\n\n  // Create the widgets for display\n  createWidgetsWrapped() catch |e| {\n    // In case of error, quit\n    std.log.err(\"createWidgetsWrapped failed: {}\", .{e});\n    return;\n  };\n\n  // Handle LVGL Tasks\n  // TODO: Call this from Web Browser JavaScript,\n  // so that Web Browser won't block\n  var i: usize = 0;\n  while (i \u003c 5) : (i += 1) {\n    _ = c.lv_timer_handler();\n  }\n```\n\nWe're ready to render the LVGL Display in our HTML Page!\n\n_Something doesn't look right..._\n\nYeah we should have called __lv_timer_handler__ from our JavaScript.\n\n(Triggered by a JavaScript Timer or __requestAnimationFrame__)\n\nBut for our quick demo, this will do. For now!\n\n![Render LVGL Display in WebAssembly](https://lupyuen.github.io/images/lvgl3-render.jpg)\n\n# Render LVGL Display in Web Browser\n\nLet's render the LVGL Display in the Web Browser! (Pic above)\n\n(Based on [daneelsan/minimal-zig-wasm-canvas](https://github.com/daneelsan/minimal-zig-wasm-canvas))\n\nLVGL renders the display pixels to `canvas_buffer`...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/5e4d661a7a9a962260d1f63c3b79a688037ed642/display.c#L95-L107\n\n[(`init_disp_buf` is called by our Zig Program)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/d584f43c6354f12bdc15bdb8632cdd3f6f5dc7ff/lvglwasm.zig#L49-L63)\n\nLVGL calls `flushDisplay` (in Zig) when the LVGL Display Canvas is ready to be rendered...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/d584f43c6354f12bdc15bdb8632cdd3f6f5dc7ff/lvglwasm.zig#L49-L63\n\n`flushDisplay` (in Zig) calls `render` (in JavaScript) to render the LVGL Display Canvas...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/d584f43c6354f12bdc15bdb8632cdd3f6f5dc7ff/lvglwasm.zig#L86-L98\n\n(Remember to call `lv_disp_flush_ready` or Web Browser will hang on reload)\n\n`render` (in JavaScript) draws the LVGL Display to our HTML Canvas...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/1ed4940d505e263727a36c362da54388be4cbca0/lvglwasm.js#L29-L53\n\nWhich calls [`getCanvasBuffer`](https://github.com/lupyuen/pinephone-lvgl-zig/blob/d584f43c6354f12bdc15bdb8632cdd3f6f5dc7ff/lvglwasm.zig#L100-L104) (in Zig) and `get_canvas_buffer` (in C) to fetch the LVGL Canvas Buffer `canvas_buffer`...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/5e4d661a7a9a962260d1f63c3b79a688037ed642/display.c#L9-L29\n\nRemember to set Direct Mode in the Display Driver!\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/86700c3453d91bc7d2fe0a46192fa41b7a24b6df/display.c#L94-L95\n\nAnd the LVGL Display renders OK in our HTML Canvas yay! (Pic below)\n\n![Render LVGL Display in Web Browser](https://lupyuen.github.io/images/zig-wasm3.png)\n\n# Handle LVGL Timer\n\nTo execute LVGL Tasks periodically, here's the proper way to handle the LVGL Timer in JavaScript...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/435435e01a4ffada2c93ecc3ec1af73a6220e7a0/feature-phone.js#L134-L150\n\n`handleTimer` comes from our Zig LVGL App, it executes LVGL Tasks periodically...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/86700c3453d91bc7d2fe0a46192fa41b7a24b6df/feature-phone.zig#L213-L222\n\n# Handle LVGL Input\n\nLet's handle Mouse and Touch Input in LVGL!\n\nWe create an LVGL Button in our Zig LVGL App...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/86700c3453d91bc7d2fe0a46192fa41b7a24b6df/feature-phone.zig#L185-L196\n\n`eventHandler` is our Zig Handler for Button Events...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/86700c3453d91bc7d2fe0a46192fa41b7a24b6df/feature-phone.zig#L198-L208\n\nWhen our app starts, we register the LVGL Input Device...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/7eb99b6c4deca82310e42d30808944f25bb6255c/feature-phone.zig#L69-L75\n\n[(We define `register_input` in C because `lv_indev_t` is an Opaque Type in Zig)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/main/display.c)\n\nThis tells LVGL to call `readInput` periodically to poll for input. (More about this below)\n\n`indev_drv` is our LVGL Input Device Driver...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/7eb99b6c4deca82310e42d30808944f25bb6255c/feature-phone.zig#L287-L288\n\nNow we handle Mouse and Touch Events in our JavaScript...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/435435e01a4ffada2c93ecc3ec1af73a6220e7a0/feature-phone.js#L77-L123\n\nWhich calls `notifyInput` in our Zig App to set the Input State and Input Coordinates...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/86700c3453d91bc7d2fe0a46192fa41b7a24b6df/feature-phone.zig#L224-L235\n\nLVGL polls our `readInput` Zig Function periodically to read the Input State and Input Coordinates...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/86700c3453d91bc7d2fe0a46192fa41b7a24b6df/feature-phone.zig#L237-L253\n\n[(We define `set_input_data` in C because `lv_indev_data_t` is an Opaque Type in Zig)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/main/display.c)\n\nAnd the LVGL Button will respond correctly to Mouse and Touch Input in the Web Browser! (Pic below)\n\n[(Try the LVGL Button Demo)](https://lupyuen.github.io/pinephone-lvgl-zig/feature-phone.html)\n\n[(Watch the demo on YouTube)](https://youtube.com/shorts/J6ugzVyKC4U?feature=share)\n\n[(See the log)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/e70b2df50fa562bec7e02f24191dbbb1e5a7553a/README.md#todo)\n\n![Handle LVGL Input](https://lupyuen.github.io/images/lvgl3-wasm4.png)\n\n# Feature Phone UI\n\nRead the article...\n\n-   [\"NuttX RTOS for PinePhone: Feature Phone UI in LVGL, Zig and WebAssembly\"](https://lupyuen.github.io/articles/lvgl4)\n\nLet's create a Feature Phone UI for PinePhone on Apache NuttX RTOS!\n\nWe create 3 LVGL Containers for the Display Label, Call / Cancel Buttons and Digit Buttons...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/b8b12209dc99a7c477aaeaa475362e795f9b05fc/feature-phone.zig#L113-L136\n\nWe create the Display Label...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/b8b12209dc99a7c477aaeaa475362e795f9b05fc/feature-phone.zig#L139-L167\n\nThen we create the Call and Cancel Buttons inside the Second Container...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/b8b12209dc99a7c477aaeaa475362e795f9b05fc/feature-phone.zig#L169-L184\n\nFinally we create the Digit Buttons inside the Third Container...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/b8b12209dc99a7c477aaeaa475362e795f9b05fc/feature-phone.zig#L186-L201\n\n[(Or use an LVGL Button Matrix)](https://docs.lvgl.io/8.3/widgets/core/btnmatrix.html)\n\nWhen we test our Zig LVGL App in WebAssembly, we see this...\n\n![Feature Phone UI](https://lupyuen.github.io/images/lvgl3-wasm5.png)\n\n[(Try the Feature Phone Demo)](https://lupyuen.github.io/pinephone-lvgl-zig/feature-phone.html)\n\n[(Watch the demo on YouTube)](https://www.youtube.com/shorts/iKa0bcSa22U)\n\n[(See the log)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/1feb919e17018222dd3ebf79b206de97eb4cfbeb/README.md#output-log)\n\n# Handle Buttons in Feature Phone UI\n\nNow that we have rendered the Feature Phone UI in Zig and LVGL, let's wire up the Buttons.\n\nClicking any Button will call our Button Event Handler...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/9650c4bc2ef8065410ca4e643cde6ab6ae2d2f7d/feature-phone.zig#L189-L197\n\nIn our Button Event Handler, we identify the Button Clicked...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/9650c4bc2ef8065410ca4e643cde6ab6ae2d2f7d/feature-phone.zig#L205-L220\n\nIf it's a Digit Button, we append the Digit to the Phone Number...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/9650c4bc2ef8065410ca4e643cde6ab6ae2d2f7d/feature-phone.zig#L238-L242\n\nIf it's the Cancel Button, we erase the last digit of the Phone Number...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/9650c4bc2ef8065410ca4e643cde6ab6ae2d2f7d/feature-phone.zig#L232-L238\n\nIf it's the Call Button, we call PinePhone's LTE Modem to dial the Phone Number...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/9650c4bc2ef8065410ca4e643cde6ab6ae2d2f7d/feature-phone.zig#L222-L231\n\n(Simulated for WebAssembly)\n\nThe buttons work OK on WebAssembly. (Pic below)\n\nLet's run the Feature Phone UI on PinePhone and Apache NuttX RTOS!\n\n![Feature Phone UI](https://lupyuen.github.io/images/lvgl3-wasm6.png)\n\n[(Try the Feature Phone Demo)](https://lupyuen.github.io/pinephone-lvgl-zig/feature-phone.html)\n\n[(Watch the demo on YouTube)](https://youtu.be/vBKhk5Q6rnE)\n\n[(See the log)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/665847f513a44648b0d4ae602d6fcf7cc364a342/README.md#output-log)\n\n# Feature Phone UI for Apache NuttX RTOS\n\n_We created an LVGL Feature Phone UI for WebAssembly. Will it run on PinePhone?_\n\nLet's refactor the LVGL Feature Phone UI, so that the same Zig Source File will run on BOTH WebAssembly and PinePhone! (With Apache NuttX RTOS)\n\nWe moved all the WebAssembly-Specific Functions to [`wasm.zig`](wasm.zig)... \n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/a0ead2b86fda34a23afee71411915ac8315537a0/wasm.zig#L19-L288\n\nOur Zig LVGL App imports [`wasm.zig`](wasm.zig) only when compiling for WebAssembly...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/0aa3a1123ae64aaa75734456ce920de23ddc6aa2/feature-phone.zig#L15-L19\n\nIn our JavaScript, we call `initDisplay` (from [`wasm.zig`](wasm.zig)) to initialise the LVGL Display and LVGL Input for WebAssembly...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/521b7c7e06beaa53b1d6c8d88671650bddaae88e/feature-phone.js#L124-L153\n\n_What about PinePhone on Apache NuttX RTOS?_\n\nWhen compiling for NuttX, our Zig LVGL App imports [`nuttx.zig`](nuttx.zig)...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/0aa3a1123ae64aaa75734456ce920de23ddc6aa2/feature-phone.zig#L15-L19\n\nWhich defines the Custom Panic Handler and Custom Logger specific to NuttX...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/f2b768eabaa99ebb0acf5454823871ddf5675a59/nuttx.zig#L7-L70\n\nWe compile our Zig LVGL App for NuttX (using the exact same Zig Source File for WebAssembly)...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/4650bc8eb5f4d23fae03d17e82b511682e288f3d/build.sh#L403-L437\n\nAnd our Feature Phone UI runs on PinePhone with NuttX yay! (Pic below)\n\nThe exact same Zig Source File runs on both WebAssembly and PinePhone, no changes needed! This is super helpful for creating LVGL Apps.\n\n![Feature Phone UI on PinePhone and Apache NuttX RTOS](https://lupyuen.github.io/images/lvgl3-pinephone.jpg)\n\n[(Watch the demo on YouTube)](https://www.youtube.com/shorts/tOUnj0XEP-Q)\n\n[(See the PinePhone Log)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/07ec0cd87b7888ac20736a7472643ee5d4758096/README.md#pinephone-log)\n\n# LVGL Fonts\n\nRemember to compile the LVGL Fonts! Or nothing will be rendered...\n\n```bash\n  ## Compile LVGL Library from C to WebAssembly with Zig Compiler\n  compile_lvgl font/lv_font_montserrat_14.c lv_font_montserrat_14\n  compile_lvgl font/lv_font_montserrat_20.c lv_font_montserrat_20\n\n  ## Compile the Zig LVGL App for WebAssembly \n  zig build-lib \\\n    -DLV_FONT_MONTSERRAT_14=1 \\\n    -DLV_FONT_MONTSERRAT_20=1 \\\n    -DLV_FONT_DEFAULT_MONTSERRAT_20=1 \\\n    -DLV_USE_FONT_PLACEHOLDER=1 \\\n    ...\n    lv_font_montserrat_14.o \\\n    lv_font_montserrat_20.o \\\n```\n\n[(Source)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/2e1c97e49e51b1cbbe0964a9512eba141d0dd09f/build.sh#L21-L191)\n\n# LVGL Memory Allocation\n\n_What happens if we omit `-DLV_MEM_CUSTOM=1`?_\n\nBy default, LVGL uses the [Two-Level Segregate Fit (TLSF) Allocator](http://www.gii.upv.es/tlsf/) for Heap Memory.\n\nBut TLSF Allocator fails in [`block_next`](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_tlsf.c#L453-L460)...\n\n```text\nmain: start\nloop: start\nlv_demo_widgets: start\nbefore lv_init\n[Info]\tlv_init: begin \t(in lv_obj.c line #102)\n[Trace]\tlv_mem_alloc: allocating 76 bytes \t(in lv_mem.c line #127)\n[Trace]\tlv_mem_alloc: allocated at 0x1a700 \t(in lv_mem.c line #160)\n[Trace]\tlv_mem_alloc: allocating 28 bytes \t(in lv_mem.c line #127)\n[Trace]\tlv_mem_alloc: allocated at 0x1a750 \t(in lv_mem.c line #160)\n[Warn]\tlv_init: Log level is set to 'Trace' which makes LVGL much slower \t(in lv_obj.c line #176)\n[Trace]\tlv_mem_realloc: reallocating 0x14 with 8 size \t(in lv_mem.c line #196)\n[Error]\tblock_next: Asserted at expression: !block_is_last(block) \t(in lv_tlsf.c line #459)\n\n004a5b4a:0x29ab2 Uncaught (in promise) RuntimeError: unreachable\n    at std.builtin.default_panic (004a5b4a:0x29ab2)\n    at lv_assert_handler (004a5b4a:0x2ac6c)\n    at block_next (004a5b4a:0xd5b3)\n    at lv_tlsf_realloc (004a5b4a:0xe226)\n    at lv_mem_realloc (004a5b4a:0x20f1)\n    at lv_layout_register (004a5b4a:0x75d8)\n    at lv_flex_init (004a5b4a:0x16afe)\n    at lv_extra_init (004a5b4a:0x16ae5)\n    at lv_init (004a5b4a:0x3f28)\n    at lv_demo_widgets (004a5b4a:0x29bb9)\n```\n\nThus we set `-DLV_MEM_CUSTOM=1` to use `malloc` instead of LVGL's TLSF Allocator.\n\n([`block_next`](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_tlsf.c#L453-L460) calls [`offset_to_block`](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_tlsf.c#L440-L444), which calls [`tlsf_cast`](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_tlsf.c#L274). Maybe the Pointer Cast doesn't work for Clang WebAssembly?)\n\n_But Zig doesn't support `malloc` for WebAssembly!_\n\nWe used Zig's FixedBufferAllocator...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/43fa982d38a7ae8f931c171a80b006a9faa95b58/lvglwasm.zig#L38-L44\n\nTo implement `malloc` ourselves...\n\nhttps://github.com/lupyuen/pinephone-lvgl-zig/blob/43fa982d38a7ae8f931c171a80b006a9faa95b58/lvglwasm.zig#L195-L237\n\n[(Remember to copy the old memory in `realloc`!)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/aade32dd70286866676b2d9728970c6b3cca9489/README.md#todo)\n\n[(If we ever remove `-DLV_MEM_CUSTOM=1`, remember to set `-DLV_MEM_SIZE=1000000`)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/aa080fb2ce55f9959cce2b6fff7e5fd5c9907cd6/README.md#lvgl-memory-allocation)\n\nTODO: How to disassemble Compiled WebAssembly with cross-reference to Source Code? Like `objdump --source`? See [wabt](https://github.com/WebAssembly/wabt) and [binaryen](https://github.com/WebAssembly/binaryen)\n\n# LVGL Screen Not Found\n\n_Why does LVGL say \"no screen found\" in [lv_obj_get_disp](https://github.com/lvgl/lvgl/blob/v8.3.3/src/core/lv_obj_tree.c#L270-L289)?_\n\nThat's because the Display Linked List `_lv_disp_ll` is allocated by `LV_ITERATE_ROOTS` in [_lv_gc_clear_roots](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_gc.c#L42)...\n\nAnd we forgot to compile [_lv_gc_clear_roots](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_gc.c#L42) in [lv_gc.c](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_gc.c#L42). Duh!\n\n(Zig Compiler assumes that missing variables like `_lv_disp_ll` are at WebAssembly Address 0)\n\nAfter compiling [_lv_gc_clear_roots](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_gc.c#L42) and [lv_gc.c](https://github.com/lvgl/lvgl/blob/v8.3.3/src/misc/lv_gc.c#L42), the \"no screen found\" error below no longer appears.\n\nTODO: Disassemble the Compiled WebAssembly and look for other Undefined Variables at WebAssembly Address 0\n\n```text\n[Info]\tlv_init: begin \t(in lv_obj.c line #102)\n[Trace]\tlv_init: finished \t(in lv_obj.c line #183)\nbefore lv_disp_drv_register\n[Warn]\tlv_obj_get_disp: No screen found \t(in lv_obj_tree.c line #290)\n[Info]\tlv_obj_create: begin \t(in lv_obj.c line #206)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x12014 class on 0 parent \t(in lv_obj_class.c line #45)\n[Warn]\tlv_obj_get_disp: No screen found \t(in lv_obj_tree.c line #290)\n```\n\n[(See the Complete Log)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/9610bb5209a072fc5950cf0559b1274d53dd8b8b/README.md#lvgl-screen-not-found)\n\n# Zig with Rancher Desktop\n\nThe [Official Zig Download for macOS](https://ziglang.org/download/) no longer runs on my 10-year-old MacBook Pro that's stuck on macOS 10.15. 😢\n\nTo run the latest version of Zig Compiler, I use Rancher Desktop and VSCode Remote Containers...\n\n- [VSCode Remote Containers on Rancher Desktop](https://docs.rancherdesktop.io/how-to-guides/vs-code-remote-containers)\n\nHere's how...\n\n1.  Install [Rancher Desktop](https://rancherdesktop.io/)\n\n1.  In Rancher Desktop, click \"Settings\"...\n\n    Set \"Container Engine\" to \"dockerd (moby)\"\n\n    Under \"Kubernetes\", uncheck \"Enable Kubernetes\"\n\n    (To reduce CPU Utilisation)\n\n1.  Restart VSCode to use the new PATH\n\n    Install the VSCode Docker Extension\n\n    In VSCode, click the Docker icon in the Left Bar\n\n1.  Under \"Containers\", click \"+\" and \"New Dev Container\"\n\n    Select \"Alpine\"\n\n1.  In a while, we'll see VSCode running inside the Alpine Linux Container\n\n    We have finally Linux on macOS!\n\n    ```text\n    $ uname -a\n    Linux bc0c45900671 5.15.96-0-virt #1-Alpine SMP Sun, 26 Feb 2023 15:14:12 +0000 x86_64 GNU/Linux\n    ```\n\n1.  Now we can download and run the latest and greatest Zig Compiler for Linux x64 [(from here)](https://ziglang.org/download/)\n\n    ```bash\n    wget https://ziglang.org/builds/zig-linux-x86_64-0.11.0-dev.3283+7cb3a6750.tar.xz\n    tar -xvf zig-linux-x86_64-0.11.0-dev.3283+7cb3a6750.tar.xz \n    zig-linux-x86_64-0.11.0-dev.3283+7cb3a6750/zig version\n    ```\n\n1.  To install the NuttX Toolchain on Alpine Linux...\n\n    [\"Build Apache NuttX RTOS on Alpine Linux\"](https://gist.github.com/lupyuen/880caa0547378028243b8cc5cfdc50a8)\n\n1.  To forward Network Ports, click the \"Ports\" tab beside \"Terminal\"\n\n    To configure other features in the Alpine Linux Container, edit the file `.devcontainer/devcontainer.json`\n\n# Zig Version\n\n(Here's what happens if we don't run Zig in a Container... We're stuck with an older version of Zig)\n\n_Which version of Zig are we using?_\n\nWe're using an older version: `0.10.0-dev.2351+b64a1d5ab`\n\nSadly Zig 0.10.1 (and later) won't run on my 10-year-old MacBook Pro that's stuck on macOS 10.15 😢\n\n```text\n→ #  Compile the Zig App for PinePhone\n  #  (armv8-a with cortex-a53)\n  #  TODO: Change \"..\" to your NuttX Project Directory\n  zig build-obj \\\n    --verbose-cimport \\\n    -target aarch64-freestanding-none \\\n    -mcpu cortex_a53 \\\n    -isystem \"../nuttx/include\" \\\n    -I \"../apps/include\" \\\n    lvgltest.zig\n\ndyld: lazy symbol binding faileddyld: lazy symbol binding faileddyld: lazy symbol binding failed: Symbol not found: ___ulock_wai: Symbol not found: ___ulock_wait2\n  Referenced from: /Users/Lupt2\n  Referenced from: /Users/Lupdyld: lazy symbol binding failedpy/zig-macos-x86_64-0.10.1/zig (py/zig-macos-x86_64-0.10.1/zig (dyld: lazy symbol binding failedwhich was built for Mac OS X 11.: Symbol not found: ___ulock_wai: Symbol not found: ___ulock_waiwhich was built for Mac OS X 11.7)\n  Expected in: /usr/lib/libSy: Symbol not found: ___ulock_wai7)\n  Expected in: /usr/lib/libSystem.B.dylib\n\nstem.B.dylib\n\nt2\n  Referenced from: /Users/Lupt2\n  Referenced from: /Users/Lupt2\n  Referenced from: /Users/Luppy/zig-macos-x86_64-0.10.1/zig (py/zig-macos-x86_64-0.10.1/zig (py/zig-macos-x86_64-0.10.1/zig (which was built for Mac OS X 11.which was built for Mac OS X 11.which was built for Mac OS X 11.7)\n  Expected in: /usr/lib/libSy7)\n  Expected in: /usr/lib/libSydyld: Symbol not found: ___ulock7)\n  Expected in: /usr/lib/libSystem.B.dylib\n\nstem.B.dylib\n\n_wait2\n  Referenced from: /Usersstem.B.dylib\n\n/Luppy/zig-macos-x86_64-0.10.1/zdyld: Symbol not found: ___ulockig (which was built for Mac OS X_wait2\n  Referenced from: /Users 11.7)\n  Expected in: /usr/lib/ldyld: Symbol not found: ___ulockdyld: Symbol not found: ___ulock/Luppy/zig-macos-x86_64-0.10.1/zibSystem.B.dylib\n\n_wait2\n  Referenced from: /Usersig (which was built for Mac OS X_wait2\n  Referenced from: /Users/Luppy/zig-macos-x86_64-0.10.1/z 11.7)\n  Expected in: /usr/lib/l/Luppy/zig-macos-x86_64-0.10.1/zig (which was built for Mac OS XibSystem.B.dylib\n\nig (which was built for Mac OS X 11.7)\n  Expected in: /usr/lib/l 11.7)\n  Expected in: /usr/lib/libSystem.B.dylib\n\nibSystem.B.dylib\n\ndyld: Symbol not found: ___ulockdyld: lazy symbol binding faileddyld: lazy symbol binding failed[1]    11157 abort      zig build-obj --verbose-cimport -target aarch64-freestanding-none -mcpu    -I\n```\n\nI tried building Zig from source, but it didn't work either...\n\n# Build Zig from Source\n\nThe [Official Zig Download for macOS](https://ziglang.org/download/) no longer runs on my 10-year-old MacBook Pro that's stuck on macOS 10.15. (See the previous section)\n\nSo I tried building Zig from Source according to these instructions...\n\n- [Building Zig from Source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source)\n\nHere's what I did...\n\n```bash\nbrew install llvm\ngit clone --recursive https://github.com/ziglang/zig\ncd zig\n\nmkdir build\ncd build\ncmake .. -DZIG_STATIC_LLVM=ON -DCMAKE_PREFIX_PATH=\"$(brew --prefix llvm);$(brew --prefix zstd)\"\nmake install\n```\n\n`brew install llvm` failed...\n\n[(Previously here)](https://github.com/lupyuen/pinephone-lvgl-zig/blob/7c6af9cd59788b67b18b85966b78f5b9aaadb10e/README.md#build-zig-from-source)\n\n[__UPDATE:__ This has been fixed](https://github.com/lupyuen/pinephone-lvgl-zig/commit/b3e395839047180b67502dbf81a358a1d604b8a9)\n\nSo I tried building LLVM from source [(from here)](https://github.com/ziglang/zig/wiki/How-to-build-LLVM,-libclang,-and-liblld-from-source#posix)...\n\n```bash\ncd ~/Downloads\ngit clone --depth 1 --branch release/16.x https://github.com/llvm/llvm-project llvm-project-16\ncd llvm-project-16\ngit checkout release/16.x\n\nmkdir build-release\ncd build-release\ncmake ../llvm \\\n  -DCMAKE_INSTALL_PREFIX=$HOME/local/llvm16-release \\\n  -DCMAKE_BUILD_TYPE=Release \\\n  -DLLVM_ENABLE_PROJECTS=\"lld;clang\" \\\n  -DLLVM_ENABLE_LIBXML2=OFF \\\n  -DLLVM_ENABLE_TERMINFO=OFF \\\n  -DLLVM_ENABLE_LIBEDIT=OFF \\\n  -DLLVM_ENABLE_ASSERTIONS=ON \\\n  -DLLVM_PARALLEL_LINK_JOBS=1 \\\n  -G Ninja\nninja install\n```\n\nBut LLVM fails to build...\n\n```text\n→ ninja install\n\n[1908/4827] Building CXX object lib/Target/AMDGPU/AsmParser/CMakeFiles/LLVMAMDGPUAsmParser.dir/AMDGPUAsmParser.cpp.o\nFAILED: lib/Target/AMDGPU/AsmParser/CMakeFiles/LLVMAMDGPUAsmParser.dir/AMDGPUAsmParser.cpp.o\n/Applications/Xcode.app/Contents/Developer/usr/bin/g++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/Users/Luppy/llvm-project-16/build-release/lib/Target/AMDGPU/AsmParser -I/Users/Luppy/llvm-project-16/llvm/lib/Target/AMDGPU/AsmParser -I/Users/Luppy/llvm-project-16/llvm/lib/Target/AMDGPU -I/Users/Luppy/llvm-project-16/build-release/lib/Target/AMDGPU -I/Users/Luppy/llvm-project-16/build-release/include -I/Users/Luppy/llvm-project-16/llvm/include -isystem /usr/local/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -Wctad-maybe-unsupported -fdiagnostics-color -O3 -DNDEBUG -std=c++17 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk  -fno-exceptions -fno-rtti -UNDEBUG -MD -MT lib/Target/AMDGPU/AsmParser/CMakeFiles/LLVMAMDGPUAsmParser.dir/AMDGPUAsmParser.cpp.o -MF lib/Target/AMDGPU/AsmParser/CMakeFiles/LLVMAMDGPUAsmParser.dir/AMDGPUAsmParser.cpp.o.d -o lib/Target/AMDGPU/AsmParser/CMakeFiles/LLVMAMDGPUAsmParser.dir/AMDGPUAsmParser.cpp.o -c /Users/Luppy/llvm-project-16/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp\n/Users/Luppy/llvm-project-16/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:5490:13: error: no viable constructor or deduction guide for deduction of template arguments of 'tuple'\n          ? std::tuple(HSAMD::V3::AssemblerDirectiveBegin,\n            ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:625:5: note: candidate template ignored: requirement '__lazy_and\u003cstd::__1::is_same\u003cstd::__1::allocator_arg_t, const char *\u003e, std::__1::__lazy_all\u003c\u003e \u003e::value' was not satisfied [with _Tp = \u003c\u003e, _AllocArgT = const char *, _Alloc = char [21], _Dummy = true]\n    tuple(_AllocArgT, _Alloc const\u0026 __a)\n    ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:641:5: note: candidate template ignored: requirement '_CheckArgsConstructor\u003ctrue, void\u003e::__enable_implicit()' was not satisfied [with _Tp = \u003cchar [17], char [21]\u003e, _Dummy = true]\n    tuple(const _Tp\u0026 ... __t) _NOEXCEPT_((__all\u003cis_nothrow_copy_constructible\u003c_Tp\u003e::value...\u003e::value))\n    ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:659:14: note: candidate template ignored: requirement '_CheckArgsConstructor\u003ctrue, void\u003e::__enable_explicit()' was not satisfied [with _Tp = \u003cchar [17], char [21]\u003e, _Dummy = true]\n    explicit tuple(const _Tp\u0026 ... __t) _NOEXCEPT_((__all\u003cis_nothrow_copy_constructible\u003c_Tp\u003e::value...\u003e::value))\n             ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:677:7: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Alloc = char [21], _Dummy = true]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n      tuple(allocator_arg_t, const _Alloc\u0026 __a, const _Tp\u0026 ... __t)\n      ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:697:7: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Alloc = char [21], _Dummy = true]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n      tuple(allocator_arg_t, const _Alloc\u0026 __a, const _Tp\u0026 ... __t)\n      ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:723:9: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Up = \u003cchar const (\u0026)[17], char const (\u0026)[21]\u003e]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n        tuple(_Up\u0026\u0026... __u)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:756:9: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Up = \u003cchar const (\u0026)[17], char const (\u0026)[21]\u003e]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n        tuple(_Up\u0026\u0026... __u)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:783:9: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Alloc = char [21], _Up = \u003c\u003e]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n        tuple(allocator_arg_t, const _Alloc\u0026 __a, _Up\u0026\u0026... __u)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:803:9: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Alloc = char [21], _Up = \u003c\u003e]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n        tuple(allocator_arg_t, const _Alloc\u0026 __a, _Up\u0026\u0026... __u)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:612:23: note: candidate function template not viable: requires 0 arguments, but 2 were provided\n    _LIBCPP_CONSTEXPR tuple()\n                      ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:615:5: note: candidate function template not viable: requires 1 argument, but 2 were provided\n    tuple(tuple const\u0026) = default;\n    ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:616:5: note: candidate function template not viable: requires 1 argument, but 2 were provided\n    tuple(tuple\u0026\u0026) = default;\n    ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:822:9: note: candidate function template not viable: requires single argument '__t', but 2 arguments were provided\n        tuple(_Tuple\u0026\u0026 __t) _NOEXCEPT_((is_nothrow_constructible\u003c_BaseT, _Tuple\u003e::value))\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:837:9: note: candidate function template not viable: requires single argument '__t', but 2 arguments were provided\n        tuple(_Tuple\u0026\u0026 __t) _NOEXCEPT_((is_nothrow_constructible\u003c_BaseT, _Tuple\u003e::value))\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:850:9: note: candidate function template not viable: requires 3 arguments, but 2 were provided\n        tuple(allocator_arg_t, const _Alloc\u0026 __a, _Tuple\u0026\u0026 __t)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:864:9: note: candidate function template not viable: requires 3 arguments, but 2 were provided\n        tuple(allocator_arg_t, const _Alloc\u0026 __a, _Tuple\u0026\u0026 __t)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:469:28: note: candidate function template not viable: requires 1 argument, but 2 were provided\nclass _LIBCPP_TEMPLATE_VIS tuple\n                           ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:932:1: note: candidate function template not viable: requires 3 arguments, but 2 were provided\ntuple(allocator_arg_t, const _Alloc\u0026, tuple\u003c_Args...\u003e const\u0026) -\u003e tuple\u003c_Args...\u003e;\n^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:934:1: note: candidate function template not viable: requires 3 arguments, but 2 were provided\ntuple(allocator_arg_t, const _Alloc\u0026, tuple\u003c_Args...\u003e\u0026\u0026) -\u003e tuple\u003c_Args...\u003e;\n^\n/Users/Luppy/llvm-project-16/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:5492:13: error: no viable constructor or deduction guide for deduction of template arguments of 'tuple'\n          : std::tuple(HSAMD::AssemblerDirectiveBegin,\n            ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:625:5: note: candidate template ignored: requirement '__lazy_and\u003cstd::__1::is_same\u003cstd::__1::allocator_arg_t, const char *\u003e, std::__1::__lazy_all\u003c\u003e \u003e::value' was not satisfied [with _Tp = \u003c\u003e, _AllocArgT = const char *, _Alloc = char [29], _Dummy = true]\n    tuple(_AllocArgT, _Alloc const\u0026 __a)\n    ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:641:5: note: candidate template ignored: requirement '_CheckArgsConstructor\u003ctrue, void\u003e::__enable_implicit()' was not satisfied [with _Tp = \u003cchar [25], char [29]\u003e, _Dummy = true]\n    tuple(const _Tp\u0026 ... __t) _NOEXCEPT_((__all\u003cis_nothrow_copy_constructible\u003c_Tp\u003e::value...\u003e::value))\n    ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:659:14: note: candidate template ignored: requirement '_CheckArgsConstructor\u003ctrue, void\u003e::__enable_explicit()' was not satisfied [with _Tp = \u003cchar [25], char [29]\u003e, _Dummy = true]\n    explicit tuple(const _Tp\u0026 ... __t) _NOEXCEPT_((__all\u003cis_nothrow_copy_constructible\u003c_Tp\u003e::value...\u003e::value))\n             ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:677:7: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Alloc = char [29], _Dummy = true]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n      tuple(allocator_arg_t, const _Alloc\u0026 __a, const _Tp\u0026 ... __t)\n      ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:697:7: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Alloc = char [29], _Dummy = true]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n      tuple(allocator_arg_t, const _Alloc\u0026 __a, const _Tp\u0026 ... __t)\n      ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:723:9: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Up = \u003cchar const (\u0026)[25], char const (\u0026)[29]\u003e]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n        tuple(_Up\u0026\u0026... __u)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:756:9: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Up = \u003cchar const (\u0026)[25], char const (\u0026)[29]\u003e]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n        tuple(_Up\u0026\u0026... __u)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:783:9: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Alloc = char [29], _Up = \u003c\u003e]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n        tuple(allocator_arg_t, const _Alloc\u0026 __a, _Up\u0026\u0026... __u)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:803:9: note: candidate template ignored: substitution failure [with _Tp = \u003c\u003e, _Alloc = char [29], _Up = \u003c\u003e]: cannot reference member of primary template because deduced class template specialization 'tuple\u003c\u003e' is an explicit specialization\n        tuple(allocator_arg_t, const _Alloc\u0026 __a, _Up\u0026\u0026... __u)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:612:23: note: candidate function template not viable: requires 0 arguments, but 2 were provided\n    _LIBCPP_CONSTEXPR tuple()\n                      ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:615:5: note: candidate function template not viable: requires 1 argument, but 2 were provided\n    tuple(tuple const\u0026) = default;\n    ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:616:5: note: candidate function template not viable: requires 1 argument, but 2 were provided\n    tuple(tuple\u0026\u0026) = default;\n    ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:822:9: note: candidate function template not viable: requires single argument '__t', but 2 arguments were provided\n        tuple(_Tuple\u0026\u0026 __t) _NOEXCEPT_((is_nothrow_constructible\u003c_BaseT, _Tuple\u003e::value))\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:837:9: note: candidate function template not viable: requires single argument '__t', but 2 arguments were provided\n        tuple(_Tuple\u0026\u0026 __t) _NOEXCEPT_((is_nothrow_constructible\u003c_BaseT, _Tuple\u003e::value))\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:850:9: note: candidate function template not viable: requires 3 arguments, but 2 were provided\n        tuple(allocator_arg_t, const _Alloc\u0026 __a, _Tuple\u0026\u0026 __t)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:864:9: note: candidate function template not viable: requires 3 arguments, but 2 were provided\n        tuple(allocator_arg_t, const _Alloc\u0026 __a, _Tuple\u0026\u0026 __t)\n        ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:469:28: note: candidate function template not viable: requires 1 argument, but 2 were provided\nclass _LIBCPP_TEMPLATE_VIS tuple\n                           ^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:932:1: note: candidate function template not viable: requires 3 arguments, but 2 were provided\ntuple(allocator_arg_t, const _Alloc\u0026, tuple\u003c_Args...\u003e const\u0026) -\u003e tuple\u003c_Args...\u003e;\n^\n/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:934:1: note: candidate function template not viable: requires 3 arguments, but 2 were provided\ntuple(allocator_arg_t, const _Alloc\u0026, tuple\u003c_Args...\u003e\u0026\u0026) -\u003e tuple\u003c_Args...\u003e;\n^\n2 errors generated.\n[1917/4827] Building CXX object lib/Target/AMDGPU/Disassembler/CMakeFiles/LLVMAMDGPUDisassembler.dir/AMDGPUDisassembler.cpp.o\nninja: build stopped: subcommand failed.\n```\n\nSo I can't build Zig from source on my 10-year-old MacBook Pro 😢\n\n# Output Log\n\nHere's the log from the JavaScript Console...\n\n```text\n main: start\nlv_demo_widgets: start\n[Info]\tlv_init: begin \t(in lv_obj.c line #102)\n[Warn]\tlv_init: Log level is set to 'Trace' which makes LVGL much slower \t(in lv_obj.c line #176)\n[Trace]\tlv_init: finished \t(in lv_obj.c line #183)\n[Info]\tlv_obj_create: begin \t(in lv_obj.c line #206)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x1773c class on 0 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating a screen \t(in lv_obj_class.c line #55)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Info]\tlv_obj_create: begin \t(in lv_obj.c line #206)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x1773c class on 0 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating a screen \t(in lv_obj_class.c line #55)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Info]\tlv_obj_create: begin \t(in lv_obj.c line #206)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x1773c class on 0 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating a screen \t(in lv_obj_class.c line #55)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\ncreateWidgets: start\n[Info]\tlv_obj_create: begin \t(in lv_obj.c line #206)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x1773c class on 0x39e320 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Info]\tlv_obj_create: begin \t(in lv_obj.c line #206)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x1773c class on 0x39e320 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Info]\tlv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\tlv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n[Info]\tlv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\tlv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n[Info]\tlv_obj_create: begin \t(in lv_obj.c line #206)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x1773c class on 0x39e320 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Info]\tlv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\tlv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39e57a parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e692 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39e9bc parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e692 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39ec98 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39ef5e parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39f237 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39f4f8 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39f7bd parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39fa86 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x39fd53 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x3a0024 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x3a02f9 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x3a05d2 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x3a08af parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x3a0b90 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\n[Info]\tlv_btn_create: begin \t(in lv_btn.c line #51)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17d4c class on 0x39e792 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_btn_constructor: begin \t(in lv_btn.c line #64)\n[Trace]\tlv_btn_constructor: finished \t(in lv_btn.c line #69)\n[Info]\tlv_label_create: begin \t(in lv_label.c line #75)\n[Trace]\tlv_obj_class_create_obj: Creating object with 0x17720 class on 0x3a0e75 parent \t(in lv_obj_class.c line #45)\n[Trace]\tlv_obj_class_create_obj: creating normal object \t(in lv_obj_class.c line #82)\n[Trace]\tlv_obj_constructor: begin \t(in lv_obj.c line #403)\n[Trace]\tlv_obj_constructor: finished \t(in lv_obj.c line #428)\n[Trace]\tlv_label_constructor: begin \t(in lv_label.c line #691)\n[Trace]\tlv_label_constructor: finished \t(in lv_label.c line #721)\ncreateWidgets: end\nlv_demo_widgets: end\n[Info]\tlv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Info]\tflex_update: update 0x39e57a container \t(in lv_flex.c line #211)\n[Info]\tflex_update: update 0x39e692 container \t(in lv_flex.c line #211)\n[Info]\tflex_update: update 0x39e792 container \t(in lv_flex.c line #211)\n[Trace]\tlv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n[Info]\tlv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Info]\tflex_update: update 0x39e57a container \t(in lv_flex.c line #211)\n[Trace]\tlv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n[Info]\tlv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\tlv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n[Info]\tlv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\tlv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n[Info]\tlv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\tlv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\nget_canvas_buffer: 803944 non-empty pixels\n main: end\n{mousedown: {…}}\nreadInput: state=1, x=162, y=491\n[Info]\t(4.322, +4056)\t indev_proc_press: pressed at x:162 y:491 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(4.355, +33)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n{mouseup: {…}}\n[Info]\t(4.373, +18)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Info]\t(4.374, +1)\t flex_update: update 0x39e57a container \t(in lv_flex.c line #211)\n[Trace]\t(4.375, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n[Info]\t(4.376, +1)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(4.377, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\nreadInput: state=0, x=162, y=491\nget_canvas_buffer: 803956 non-empty pixels\nget_canvas_buffer: 803952 non-empty pixels\n2get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=334, y=494\n[Info]\t(4.689, +312)\t indev_proc_press: pressed at x:334 y:494 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(4.721, +32)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(4.740, +19)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(4.741, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=334, y=494\nget_canvas_buffer: 803956 non-empty pixels\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=570, y=493\n[Info]\t(5.108, +367)\t indev_proc_press: pressed at x:570 y:493 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(5.158, +50)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(5.162, +4)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(5.163, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=570, y=493\nget_canvas_buffer: 803956 non-empty pixels\nget_canvas_buffer: 803952 non-empty pixels\nget_canvas_buffer: 803940 non-empty pixels\nget_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=186, y=669\n[Info]\t(6.075, +912)\t indev_proc_press: pressed at x:186 y:669 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(6.106, +31)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(6.124, +18)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(6.125, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=186, y=669\nget_canvas_buffer: 803956 non-empty pixels\nget_canvas_buffer: 803952 non-empty pixels\nget_canvas_buffer: 803940 non-empty pixels\nget_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=336, y=643\n[Info]\t(6.474, +349)\t indev_proc_press: pressed at x:336 y:643 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(6.509, +35)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(6.513, +4)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(6.514, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=336, y=643\nget_canvas_buffer: 803952 non-empty pixels\nget_canvas_buffer: 803944 non-empty pixels\nget_canvas_buffer: 803940 non-empty pixels\nget_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=519, y=631\n[Info]\t(6.941, +427)\t indev_proc_press: pressed at x:519 y:631 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(6.975, +34)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(6.979, +4)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(6.980, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=519, y=631\nget_canvas_buffer: 803952 non-empty pixels\nget_canvas_buffer: 803698 non-empty pixels\nget_canvas_buffer: 803956 non-empty pixels\n2get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=559, y=282\n[Info]\t(7.725, +745)\t indev_proc_press: pressed at x:559 y:282 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(7.757, +32)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(7.775, +18)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(7.776, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\nget_canvas_buffer: 803956 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=559, y=282\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=559, y=282\n[Info]\t(8.159, +383)\t indev_proc_press: pressed at x:559 y:282 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(8.191, +32)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(8.209, +18)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(8.210, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nget_canvas_buffer: 803956 non-empty pixels\nreadInput: state=0, x=559, y=282\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=559, y=282\n[Info]\t(8.493, +283)\t indev_proc_press: pressed at x:559 y:282 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(8.525, +32)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(8.543, +18)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(8.544, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nget_canvas_buffer: 803956 non-empty pixels\nreadInput: state=0, x=559, y=282\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=155, y=643\n[Info]\t(9.376, +832)\t indev_proc_press: pressed at x:155 y:643 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(9.408, +32)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(9.427, +19)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(9.428, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\nget_canvas_buffer: 803956 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=155, y=643\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=327, y=640\n[Info]\t(9.844, +416)\t indev_proc_press: pressed at x:327 y:640 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(9.876, +32)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(9.894, +18)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(9.895, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=327, y=640\nget_canvas_buffer: 803956 non-empty pixels\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=554, y=637\n[Info]\t(10.362, +467)\t indev_proc_press: pressed at x:554 y:637 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(10.392, +30)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(10.411, +19)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(10.412, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\nget_canvas_buffer: 803956 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=554, y=637\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=197, y=768\n[Info]\t(11.029, +617)\t indev_proc_press: pressed at x:197 y:768 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(11.059, +30)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(11.081, +22)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(11.082, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\nget_canvas_buffer: 803956 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=197, y=768\nget_canvas_buffer: 803952 non-empty pixels\nget_canvas_buffer: 803940 non-empty pixels\nget_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=362, y=766\n[Info]\t(11.428, +346)\t indev_proc_press: pressed at x:362 y:766 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(11.460, +32)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(11.478, +18)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(11.479, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=362, y=766\nget_canvas_buffer: 803956 non-empty pixels\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=593, y=769\n[Info]\t(11.895, +416)\t indev_proc_press: pressed at x:593 y:769 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(11.928, +33)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(11.945, +17)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(11.946, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=593, y=769\nget_canvas_buffer: 803956 non-empty pixels\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=368, y=915\n[Info]\t(12.629, +683)\t indev_proc_press: pressed at x:368 y:915 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(12.662, +33)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\n[Info]\t(12.680, +18)\t lv_obj_update_layout: Layout update begin \t(in lv_obj_pos.c line #314)\n[Trace]\t(12.681, +1)\t lv_obj_update_layout: Layout update end \t(in lv_obj_pos.c line #317)\n2get_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nreadInput: state=0, x=368, y=915\nget_canvas_buffer: 803956 non-empty pixels\nget_canvas_buffer: 803952 non-empty pixels\nget_canvas_buffer: 803940 non-empty pixels\nget_canvas_buffer: 803944 non-empty pixels\n{mousedown: {…}}\nreadInput: state=1, x=219, y=274\n[Info]\t(13.328, +647)\t indev_proc_press: pressed at x:219 y:274 \t(in lv_indev.c line #819)\nget_canvas_buffer: 803944 non-empty pixels\n[Info]\t(13.361, +33)\t indev_proc_release: released \t(in lv_indev.c line #969)\neventHandler: clicked\nCall +1234567890\nRunning in WebAssembly, simulate the Phone Call\nget_canvas_buffer: 803944 non-empty pixels\n{mouseup: {…}}\nget_canvas_buffer: 803956 non-empty pixels\nreadInput: state=0, x=219, y=274\nget_canvas_buffer: 803952 non-empty pixels\n3get_canvas_buffer: 803944 non-empty pixels\n```\n\n# PinePhone Log\n\nHere's the log from PinePhone on Apache NuttX RTOS...\n\n```text\nDRAM: 2048 MiB\nTrying to boot from MMC1\nNOTICE:  BL31: v2.2(release):v2.2-904-gf9ea3a629\nNOTICE:  BL31: Built : 15:32:12, Apr  9 2020\nNOTICE:  BL31: Detected Allwinner A64/H64/R18 SoC (1689)\nNOTICE:  BL31: Found U-Boot DTB at 0x4064410, model: PinePhone\nNOTICE:  PSCI: System suspend is unavailable\n\n\nU-Boot 2020.07 (Nov 08 2020 - 00:15:12 +0100)\n\nDRAM:  2 GiB\nMMC:   Device 'mmc@1c11000': seq 1 is in use by 'mmc@1c10000'\nmmc@1c0f000: 0, mmc@1c10000: 2, mmc@1c11000: 1\nLoading Environment from FAT... *** Warning - bad CRC, using default environment\n\nstarting USB...\nNo working controllers found\nHit any key to stop autoboot:  0 \nswitch to partitions #0, OK\nmmc0 is current device\nScanning mmc 0:1...\nFound U-Boot script /boot.scr\n653 bytes read in 3 ms (211.9 KiB/s)\n## Executing script at 4fc00000\ngpio: pin 114 (gpio 114) value is 1\n276622 bytes read in 16 ms (16.5 MiB/s)\nUncompressed size: 10387456 = 0x9E8000\n36162 bytes read in 4 ms (8.6 MiB/s)\n1078500 bytes read in 50 ms (20.6 MiB/s)\n## Flattened Device Tree blob at 4fa00000\n   Booting using the fdt blob at 0x4fa00000\n   Loading Ramdisk to 49ef8000, end 49fff4e4 ... OK\n   Loading Device Tree to 0000000049eec000, end 0000000049ef7d41 ... OK\n\nStarting kernel ...\n\nnsh: mkfatfs: command not found\n\nNuttShell (NSH) NuttX-12.0.3\nnsh\u003e lvgldemo\nlv_demo_widgets: start\ncreateWidgets: start\ncreateWidgets: end\nlv_demo_widgets: end\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\neventHandler: clicked\nCall +1234567890\nRunning on PinePhone, make an actual Phone Call\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flupyuen%2Fpinephone-lvgl-zig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flupyuen%2Fpinephone-lvgl-zig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flupyuen%2Fpinephone-lvgl-zig/lists"}