mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-26 19:15:38 +08:00
fix(nuttx): fix gesture event failure (#5996)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: Benign X <1341398182@qq.com>
This commit is contained in:
@@ -34,6 +34,8 @@
|
||||
typedef struct {
|
||||
/* fd should be defined at the beginning */
|
||||
int fd;
|
||||
struct touch_sample_s last_sample;
|
||||
bool has_last_sample;
|
||||
lv_indev_state_t last_state;
|
||||
lv_indev_t * indev_drv;
|
||||
} lv_nuttx_touchscreen_t;
|
||||
@@ -85,38 +87,71 @@ lv_indev_t * lv_nuttx_touchscreen_create(const char * dev_path)
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void conv_touch_sample(lv_indev_t * drv,
|
||||
lv_indev_data_t * data,
|
||||
struct touch_sample_s * sample)
|
||||
{
|
||||
lv_nuttx_touchscreen_t * touchscreen = drv->driver_data;
|
||||
uint8_t touch_flags = sample->point[0].flags;
|
||||
|
||||
if(touch_flags & (TOUCH_DOWN | TOUCH_MOVE)) {
|
||||
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, sample->point[0].x, hor_max);
|
||||
data->point.y = LV_CLAMP(0, sample->point[0].y, ver_max);
|
||||
touchscreen->last_state = LV_INDEV_STATE_PRESSED;
|
||||
}
|
||||
else if(touch_flags & TOUCH_UP) {
|
||||
touchscreen->last_state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
static bool touchscreen_read_sample(int fd, struct touch_sample_s * sample)
|
||||
{
|
||||
int nbytes = read(fd, sample, sizeof(struct touch_sample_s));
|
||||
return nbytes == sizeof(struct touch_sample_s);
|
||||
}
|
||||
|
||||
static void touchscreen_read(lv_indev_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
lv_nuttx_touchscreen_t * touchscreen = drv->driver_data;
|
||||
struct touch_sample_s sample;
|
||||
|
||||
/* Read one sample */
|
||||
/*
|
||||
* Note: Since it is necessary to avoid multi-processing click events
|
||||
* caused by redundant continue_reading, a two-unit sample sliding window
|
||||
* algorithm is used here. continue_reading is only activated when there
|
||||
* are two points in the window.
|
||||
*/
|
||||
|
||||
int nbytes = read(touchscreen->fd, &sample,
|
||||
sizeof(struct touch_sample_s));
|
||||
|
||||
/* Handle unexpected return values */
|
||||
|
||||
if(nbytes == sizeof(struct touch_sample_s)) {
|
||||
uint8_t touch_flags = sample.point[0].flags;
|
||||
|
||||
if(touch_flags & TOUCH_DOWN || touch_flags & TOUCH_MOVE) {
|
||||
const lv_display_t * disp_drv = drv->disp;
|
||||
int32_t ver_max = disp_drv->ver_res - 1;
|
||||
int32_t hor_max = disp_drv->hor_res - 1;
|
||||
|
||||
data->point.x = LV_CLAMP(0, sample.point[0].x, hor_max);
|
||||
data->point.y = LV_CLAMP(0, sample.point[0].y, ver_max);
|
||||
touchscreen->last_state = LV_INDEV_STATE_PRESSED;
|
||||
}
|
||||
else if(touch_flags & TOUCH_UP) {
|
||||
touchscreen->last_state = LV_INDEV_STATE_RELEASED;
|
||||
/* If has last sample, use it first */
|
||||
if(touchscreen->has_last_sample) {
|
||||
conv_touch_sample(drv, data, &touchscreen->last_sample);
|
||||
}
|
||||
else {
|
||||
/* Read first sample */
|
||||
if(!touchscreen_read_sample(touchscreen->fd, &sample)) {
|
||||
/* No sample available, return last state */
|
||||
data->state = touchscreen->last_state;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read until the last point */
|
||||
conv_touch_sample(drv, data, &sample);
|
||||
}
|
||||
|
||||
/* Try to read next sample */
|
||||
if(touchscreen_read_sample(touchscreen->fd, &sample)) {
|
||||
/* Save last sample and let lvgl continue reading */
|
||||
touchscreen->last_sample = sample;
|
||||
touchscreen->has_last_sample = true;
|
||||
data->continue_reading = true;
|
||||
}
|
||||
else {
|
||||
/* No more sample available, clear last sample flag */
|
||||
touchscreen->has_last_sample = false;
|
||||
}
|
||||
|
||||
data->state = touchscreen->last_state;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user