Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modules: lvgl: Fix coordinate handling for invert-{x,y} and swap-xy #70541

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions modules/lvgl/input/lvgl_keypad_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ static void lvgl_keypad_process_event(const struct device *dev, struct input_eve
}

data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event,
K_NO_WAIT) != 0) {
if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event, K_NO_WAIT) != 0) {
LOG_WRN("Could not put input data into keypad queue");
}
}
Expand Down
68 changes: 36 additions & 32 deletions modules/lvgl/input/lvgl_pointer_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,74 +21,77 @@ struct lvgl_pointer_input_config {
bool invert_y;
};

struct lvgl_pointer_input_data {
struct lvgl_common_input_data common_data;
uint32_t point_x;
uint32_t point_y;
};

static void lvgl_pointer_process_event(const struct device *dev, struct input_event *evt)
{
const struct lvgl_pointer_input_config *cfg = dev->config;
struct lvgl_common_input_data *data = dev->data;
struct lvgl_pointer_input_data *data = dev->data;
lv_disp_t *disp = lv_disp_get_default();
struct lvgl_disp_data *disp_data = disp->driver->user_data;
struct display_capabilities *cap = &disp_data->cap;
lv_point_t *point = &data->pending_event.point;
lv_point_t *point = &data->common_data.pending_event.point;

switch (evt->code) {
case INPUT_ABS_X:
point->x = evt->value;
if (cfg->swap_xy) {
data->point_y = evt->value;
} else {
data->point_x = evt->value;
}
break;
case INPUT_ABS_Y:
point->y = evt->value;
if (cfg->swap_xy) {
data->point_x = evt->value;
} else {
data->point_y = evt->value;
}
break;
case INPUT_BTN_TOUCH:
data->pending_event.state = evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
data->common_data.pending_event.state =
evt->value ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
break;
}

if (!evt->sync) {
return;
}

/* adjust coordinates */
if (cfg->swap_xy) {
lv_coord_t tmp;

tmp = point->x;
point->x = point->y;
point->y = tmp;
}
point->x = data->point_x;
point->y = data->point_y;

if (cfg->invert_x) {
if (cap->current_orientation == DISPLAY_ORIENTATION_NORMAL ||
cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
point->x = cap->x_resolution - point->x;
point->x = cap->x_resolution - data->point_x;
} else {
point->x = cap->y_resolution - point->x;
point->x = cap->y_resolution - data->point_x;
}
}

if (cfg->invert_y) {
if (cap->current_orientation == DISPLAY_ORIENTATION_NORMAL ||
cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
point->y = cap->y_resolution - point->y;
point->y = cap->y_resolution - data->point_y;
} else {
point->y = cap->x_resolution - point->y;
point->y = cap->x_resolution - data->point_y;
}
}

/* rotate touch point to match display rotation */
if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_90) {
lv_coord_t tmp;

tmp = point->x;
point->x = point->y;
point->y = cap->y_resolution - tmp;
point->x = data->point_y;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right. If cfg->invert_x or cfg->invert_y are set, AND the display orientation is rotated, you overwrite the inversion.

Copy link
Contributor

@larsgk larsgk May 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is what breaks input for me too. I am using the Adafruit 2.8 shield and trying to just do a simple tab view. The input seems to "work" by pressing the inverse x & y positions (like the input detection is rotated 180 degrees).

FYI, I am just using the default 90 degree orientation set in the devicetree defs for the shield

point->y = cap->y_resolution - data->point_x;
} else if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_180) {
point->x = cap->x_resolution - point->x;
point->y = cap->y_resolution - point->y;
point->x = cap->x_resolution - data->point_x;
point->y = cap->y_resolution - data->point_y;
} else if (cap->current_orientation == DISPLAY_ORIENTATION_ROTATED_270) {
lv_coord_t tmp;

tmp = point->x;
point->x = cap->x_resolution - point->y;
point->y = tmp;
point->x = cap->x_resolution - data->point_y;
point->y = data->point_x;
}

/* filter readings within display */
Expand All @@ -104,7 +107,8 @@ static void lvgl_pointer_process_event(const struct device *dev, struct input_ev
point->y = cap->y_resolution - 1;
}

if (k_msgq_put(cfg->common_config.event_msgq, &data->pending_event, K_NO_WAIT) != 0) {
if (k_msgq_put(cfg->common_config.event_msgq, &data->common_data.pending_event,
K_NO_WAIT) != 0) {
LOG_WRN("Could not put input data into queue");
}
}
Expand All @@ -123,8 +127,8 @@ int lvgl_pointer_input_init(const struct device *dev)
.invert_x = DT_INST_PROP(inst, invert_x), \
.invert_y = DT_INST_PROP(inst, invert_y), \
}; \
static struct lvgl_common_input_data lvgl_common_input_data_##inst; \
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &lvgl_common_input_data_##inst, \
static struct lvgl_pointer_input_data lvgl_pointer_input_data_##inst; \
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &lvgl_pointer_input_data_##inst, \
&lvgl_pointer_input_config_##inst, POST_KERNEL, \
CONFIG_INPUT_INIT_PRIORITY, NULL);

Expand Down
Loading