// SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @brief Trackball operating mode. */ enum LvglTrackballMode { /** Navigation via enc_diff (scroll wheel behavior). No cursor is shown. */ LVGL_TRACKBALL_MODE_ENCODER, /** Mouse cursor via point.x/point.y. A cursor is shown if an image was set via * lvgl_trackball_set_cursor_image(). */ LVGL_TRACKBALL_MODE_POINTER }; /** * @brief Runtime-adjustable trackball behavior. See lvgl_trackball_set_settings()/ * lvgl_trackball_get_settings(). */ struct LvglTrackballSettings { enum LvglTrackballMode mode; /** When false, movement and button presses are drained from the device and discarded: * the indev reports no movement and stays released. */ bool enabled; /** Encoder mode: steps per raw trackball tick. Must be >= 1. */ uint8_t encoder_sensitivity; /** Pointer mode: pixels per raw trackball tick. Must be >= 1. */ uint8_t pointer_sensitivity; }; /** * @brief Creates an lv_indev_t bound to the given TRACKBALL_TYPE device and registers a read * callback that polls the device through its TrackballApi. * * The indev starts in LVGL_TRACKBALL_MODE_ENCODER, enabled, with default sensitivities (see * lvgl_trackball_settings_get_default()). Call lvgl_trackball_set_settings() to change this, * e.g. to switch to pointer mode - each device added this way can independently run with or * without pointer support. * * @warning Caller must hold the LVGL lock (see lvgl_lock() in lvgl_module.h) — call this from * LvglModuleConfig.on_start, or after calling lvgl_lock() explicitly. * * @param[in] device a device of type TRACKBALL_TYPE * @param[in] display the display this indev should be associated with, or NULL to leave it unset * @param[out] out_indev the created indev, valid only when ERROR_NONE is returned * @retval ERROR_NONE on success * @retval ERROR_INVALID_ARGUMENT if device or out_indev is NULL, or device is not of type TRACKBALL_TYPE * @retval ERROR_OUT_OF_MEMORY if allocation failed */ error_t lvgl_trackball_add(struct Device* device, lv_display_t* display, lv_indev_t** out_indev); /** * @brief Removes an indev previously created with lvgl_trackball_add(), including its cursor * object (if one was showing). * @warning Caller must hold the LVGL lock. */ void lvgl_trackball_remove(lv_indev_t* indev); /** * @return the default (all fields explicitly set) LvglTrackballSettings: encoder mode, enabled, * encoder_sensitivity 1, pointer_sensitivity 10. */ struct LvglTrackballSettings lvgl_trackball_settings_get_default(void); /** * @brief Applies settings to an indev previously created with lvgl_trackball_add(). Switching * `mode` shows/hides the cursor (pointer mode) and re-centers it on the indev's display. * @warning Caller must hold the LVGL lock. * @param[in] indev an indev previously created by lvgl_trackball_add() * @param[in] settings the settings to apply * @retval ERROR_NONE on success * @retval ERROR_INVALID_ARGUMENT if indev or settings is NULL, or either sensitivity is 0 */ error_t lvgl_trackball_set_settings(lv_indev_t* indev, const struct LvglTrackballSettings* settings); /** * @brief Retrieves the settings currently active on indev. * @warning Caller must hold the LVGL lock. * @return true when indev is a trackball indev (out_settings is filled), false otherwise */ bool lvgl_trackball_get_settings(lv_indev_t* indev, struct LvglTrackballSettings* out_settings); /** * @brief Sets the image shown as the mouse cursor while indev is in LVGL_TRACKBALL_MODE_POINTER. * lvgl-module has no bundled cursor asset (it doesn't depend on any particular asset layout), so * pointer mode has no visible cursor until a caller supplies one here; the indev still moves and * reports point.x/point.y either way. Pass NULL to remove the cursor. * @warning Caller must hold the LVGL lock. * @param[in] indev an indev previously created by lvgl_trackball_add() * @param[in] image_src an LVGL image source (as accepted by lv_image_set_src()), or NULL */ void lvgl_trackball_set_cursor_image(lv_indev_t* indev, const void* image_src); #ifdef __cplusplus } #endif