From b68caaf7f9ca2b75a092f4504b1dc0ca061b443f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=A2=E6=A1=83=E5=85=AD?= Date: Fri, 4 Jul 2025 15:08:38 +0800 Subject: [PATCH] feat(nuttx) : add mouse capabilities to applications (#8425) --- Kconfig | 13 ++ lv_conf_template.h | 8 +- src/drivers/nuttx/lv_nuttx_entry.c | 14 ++ src/drivers/nuttx/lv_nuttx_entry.h | 2 + src/drivers/nuttx/lv_nuttx_mouse.c | 200 +++++++++++++++++++++++++++++ src/drivers/nuttx/lv_nuttx_mouse.h | 57 ++++++++ src/lv_conf_internal.h | 24 +++- 7 files changed, 316 insertions(+), 2 deletions(-) create mode 100644 src/drivers/nuttx/lv_nuttx_mouse.c create mode 100644 src/drivers/nuttx/lv_nuttx_mouse.h diff --git a/Kconfig b/Kconfig index 6ed9f2ebfd..646209d3d9 100644 --- a/Kconfig +++ b/Kconfig @@ -2033,6 +2033,19 @@ menu "LVGL configuration" help Set to 0 to disable cursor, or set to a value greater than 0 to set the cursor size in pixels. + config LV_USE_NUTTX_MOUSE + bool "Use NuttX mouse driver" + depends on LV_USE_NUTTX + default n + + config LV_USE_NUTTX_MOUSE_MOVE_STEP + int "Mouse movement step (pixels)" + depends on LV_USE_NUTTX_MOUSE + range 1 10 + default 1 + help + Set the step size of the mouse movement in pixels. + config LV_USE_LINUX_DRM bool "Use Linux DRM device" default n diff --git a/lv_conf_template.h b/lv_conf_template.h index b8255ac05d..61b0b28c2a 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1250,8 +1250,14 @@ /** Driver for /dev/input */ #define LV_USE_NUTTX_TOUCHSCREEN 0 - /*Touchscreen cursor size in pixels(<=0: disable cursor)*/ + /** Touchscreen cursor size in pixels(<=0: disable cursor) */ #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 + + /** Driver for /dev/mouse */ + #define LV_USE_NUTTX_MOUSE 0 + + /** Mouse movement step (pixels) */ + #define LV_USE_NUTTX_MOUSE_MOVE_STEP 1 #endif /** Driver for /dev/dri/card */ diff --git a/src/drivers/nuttx/lv_nuttx_entry.c b/src/drivers/nuttx/lv_nuttx_entry.c index 76e1af1b65..03fd167b81 100644 --- a/src/drivers/nuttx/lv_nuttx_entry.c +++ b/src/drivers/nuttx/lv_nuttx_entry.c @@ -19,6 +19,7 @@ #include "lv_nuttx_image_cache.h" #include "../../core/lv_global.h" #include "lv_nuttx_profiler.h" +#include "lv_nuttx_mouse.h" #include "../../../lvgl.h" @@ -106,6 +107,10 @@ void lv_nuttx_dsc_init(lv_nuttx_dsc_t * dsc) #ifdef CONFIG_UINPUT_TOUCH dsc->utouch_path = "/dev/utouch"; #endif + +#if LV_USE_NUTTX_MOUSE + dsc->mouse_path = "/dev/mouse0"; +#endif } void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) @@ -167,6 +172,15 @@ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) } } #endif + +#if LV_USE_NUTTX_MOUSE + if(dsc->mouse_path) { + lv_indev_t * indev = lv_nuttx_mouse_create(dsc->mouse_path); + if(result) { + result->mouse_indev = indev; + } + } +#endif } #else diff --git a/src/drivers/nuttx/lv_nuttx_entry.h b/src/drivers/nuttx/lv_nuttx_entry.h index 049e741e5f..a23bb99082 100644 --- a/src/drivers/nuttx/lv_nuttx_entry.h +++ b/src/drivers/nuttx/lv_nuttx_entry.h @@ -35,12 +35,14 @@ typedef struct { const char * fb_path; const char * input_path; const char * utouch_path; + const char * mouse_path; } lv_nuttx_dsc_t; typedef struct { lv_display_t * disp; lv_indev_t * indev; lv_indev_t * utouch_indev; + lv_indev_t * mouse_indev; } lv_nuttx_result_t; typedef struct _lv_nuttx_ctx_t { diff --git a/src/drivers/nuttx/lv_nuttx_mouse.c b/src/drivers/nuttx/lv_nuttx_mouse.c new file mode 100644 index 0000000000..211669408c --- /dev/null +++ b/src/drivers/nuttx/lv_nuttx_mouse.c @@ -0,0 +1,200 @@ +/** + * @file lv_nuttx_mouse.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_nuttx_mouse.h" + +#if LV_USE_NUTTX + +#if LV_USE_NUTTX_MOUSE + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + int fd; + lv_indev_state_t last_state; +} lv_nuttx_mouse_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void mouse_read(lv_indev_t * drv, lv_indev_data_t * data); +static void mouse_delete_cb(lv_event_t * e); +static lv_indev_t * mouse_init(int fd); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_indev_t * lv_nuttx_mouse_create(const char * dev_path) +{ + lv_indev_t * indev; + int fd; + + LV_ASSERT_NULL(dev_path); + LV_LOG_USER("mouse %s opening", dev_path); + fd = open(dev_path, O_RDONLY | O_NONBLOCK); + if(fd < 0) { + LV_LOG_ERROR("Error: cannot open mouse device"); + return NULL; + } + + LV_LOG_USER("mouse %s open success", dev_path); + + indev = mouse_init(fd); + + if(indev == NULL) { + close(fd); + } + + return indev; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void mouse_read(lv_indev_t * drv, lv_indev_data_t * data) +{ + lv_nuttx_mouse_t * mouse = drv->driver_data; + struct mouse_report_s sample; + + /* Read one sample */ + + int nbytes = read(mouse->fd, &sample, sizeof(struct mouse_report_s)); + + /* Handle unexpected return values */ + + if(nbytes == sizeof(struct mouse_report_s)) { + lv_display_t * disp = lv_indev_get_display(drv); + int32_t hor_max = lv_display_get_horizontal_resolution(disp) - 1; + int32_t ver_max = lv_display_get_vertical_resolution(disp) - 1; + + data->point.x = + LV_CLAMP(0, + data->point.x + (sample.x * LV_USE_NUTTX_MOUSE_MOVE_STEP), + hor_max); + data->point.y = + LV_CLAMP(0, + data->point.y + (sample.y * LV_USE_NUTTX_MOUSE_MOVE_STEP), + ver_max); + + uint8_t mouse_buttons = sample.buttons; + + if(mouse_buttons & MOUSE_BUTTON_1 || mouse_buttons & MOUSE_BUTTON_2 || + mouse_buttons & MOUSE_BUTTON_3) { + mouse->last_state = LV_INDEV_STATE_PRESSED; + } + else { + mouse->last_state = LV_INDEV_STATE_RELEASED; + } + } + else { + if(nbytes == -1) { + if(errno != EAGAIN) { + LV_LOG_WARN("Read error: %s", strerror(errno)); + } + } + else if(nbytes != 0) { + LV_LOG_WARN("Unexpected read size: %d", nbytes); + } + } + + data->state = mouse->last_state; +} + +static void mouse_delete_cb(lv_event_t * e) +{ + lv_indev_t * indev = lv_event_get_user_data(e); + lv_nuttx_mouse_t * mouse = lv_indev_get_driver_data(indev); + if(mouse) { + lv_indev_set_driver_data(indev, NULL); + lv_indev_set_read_cb(indev, NULL); + + if(mouse->fd >= 0) { + close(mouse->fd); + mouse->fd = -1; + } + lv_free(mouse); + LV_LOG_USER("done"); + } +} + +static void mouse_set_cursor(lv_indev_t * indev) +{ + lv_obj_t * cursor_obj = lv_obj_create(lv_layer_sys()); + lv_obj_remove_style_all(cursor_obj); + + int32_t size = 20; + lv_obj_set_size(cursor_obj, size, size); + lv_obj_set_style_translate_x(cursor_obj, -size / 2, 0); + lv_obj_set_style_translate_y(cursor_obj, -size / 2, 0); + lv_obj_set_style_radius(cursor_obj, LV_RADIUS_CIRCLE, 0); + lv_obj_set_style_bg_opa(cursor_obj, LV_OPA_50, 0); + lv_obj_set_style_bg_color(cursor_obj, lv_color_black(), 0); + lv_obj_set_style_border_width(cursor_obj, 2, 0); + lv_obj_set_style_border_color(cursor_obj, + lv_palette_main(LV_PALETTE_GREY), 0); + lv_indev_set_cursor(indev, cursor_obj); +} + +static lv_indev_t * mouse_init(int fd) +{ + lv_nuttx_mouse_t * mouse; + lv_indev_t * indev = NULL; + + mouse = lv_malloc_zeroed(sizeof(lv_nuttx_mouse_t)); + LV_ASSERT_MALLOC(mouse); + + mouse->fd = fd; + mouse->last_state = LV_INDEV_STATE_RELEASED; + indev = lv_indev_create(); + + if(indev == NULL) { + LV_LOG_ERROR("indev create failed"); + lv_free(mouse); + return NULL; + } + + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, mouse_read); + lv_indev_set_driver_data(indev, mouse); + lv_indev_add_event_cb(indev, mouse_delete_cb, LV_EVENT_DELETE, indev); + + /* Set cursor icon */ + mouse_set_cursor(indev); + return indev; +} + +#endif /*LV_USE_NUTTX_MOUSE*/ + +#endif /* LV_USE_NUTTX*/ diff --git a/src/drivers/nuttx/lv_nuttx_mouse.h b/src/drivers/nuttx/lv_nuttx_mouse.h new file mode 100644 index 0000000000..dfde8e8074 --- /dev/null +++ b/src/drivers/nuttx/lv_nuttx_mouse.h @@ -0,0 +1,57 @@ +/** + * @file lv_nuttx_mouse.h + * + */ + +/********************* + * INCLUDES + *********************/ + +#ifndef LV_NUTTX_MOUSE_H +#define LV_NUTTX_MOUSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" + +#if LV_USE_NUTTX + +#if LV_USE_NUTTX_MOUSE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize indev with specified input device. + * @param dev_path path of input device + */ +lv_indev_t * lv_nuttx_mouse_create(const char * dev_path); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_NUTTX_MOUSE */ + +#endif /* LV_USE_NUTTX*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LV_NUTTX_MOUSE_H */ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 077f8aa009..aa9a96b3ef 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -4061,7 +4061,7 @@ #endif #endif - /*Touchscreen cursor size in pixels(<=0: disable cursor)*/ + /** Touchscreen cursor size in pixels(<=0: disable cursor) */ #ifndef LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE #ifdef CONFIG_LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE CONFIG_LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE @@ -4069,6 +4069,28 @@ #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 #endif #endif + + /** Driver for /dev/mouse */ + #ifndef LV_USE_NUTTX_MOUSE + #ifdef CONFIG_LV_USE_NUTTX_MOUSE + #define LV_USE_NUTTX_MOUSE CONFIG_LV_USE_NUTTX_MOUSE + #else + #define LV_USE_NUTTX_MOUSE 0 + #endif + #endif + + /** Mouse movement step (pixels) */ + #ifndef LV_USE_NUTTX_MOUSE_MOVE_STEP + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_NUTTX_MOUSE_MOVE_STEP + #define LV_USE_NUTTX_MOUSE_MOVE_STEP CONFIG_LV_USE_NUTTX_MOUSE_MOVE_STEP + #else + #define LV_USE_NUTTX_MOUSE_MOVE_STEP 0 + #endif + #else + #define LV_USE_NUTTX_MOUSE_MOVE_STEP 1 + #endif + #endif #endif /** Driver for /dev/dri/card */