Skip to content

Commit

Permalink
modules: lvgl: Sync display rotation to LVGL
Browse files Browse the repository at this point in the history
LVGL supports the `rotated` flag on its display drivers. It is used
during input device coordinate processing to translate the physical
touch points to the points in (rendered) GUI space. Previously this was
done by the Zephyr gluecode on system init. With this change it is now
possible to perform runtime rotation of the display, the
`lvgl_reload_display_capabilities` method should be called right after
`display_set_orientation`.

Signed-off-by: Fabian Blatz <fabianblatz@gmail.com>
  • Loading branch information
faxe1008 committed May 31, 2024
1 parent 190c542 commit 5d1112b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 30 deletions.
41 changes: 11 additions & 30 deletions modules/lvgl/input/lvgl_pointer_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,65 +61,46 @@ static void lvgl_pointer_process_event(const struct device *dev, struct input_ev
return;
}

lv_point_t tmp_point = {
.x = data->point_x,
.y = data->point_y,
};
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) {
tmp_point.x = cap->x_resolution - tmp_point.x;
point->x = cap->x_resolution - point->x;
} else {
tmp_point.x = cap->y_resolution - tmp_point.x;
point->x = cap->y_resolution - point->x;
}
}

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

/* rotate touch point to match display rotation */
/* Compensate off-by-one error in LVGL rotation code (lv_indev.c) */
switch (cap->current_orientation) {
case DISPLAY_ORIENTATION_NORMAL:
point->x = tmp_point.x;
point->y = tmp_point.y;
break;
case DISPLAY_ORIENTATION_ROTATED_90:
point->x = tmp_point.y;
point->y = cap->y_resolution - tmp_point.x;
point->y -= 1;
break;
case DISPLAY_ORIENTATION_ROTATED_180:
point->x = cap->x_resolution - tmp_point.x;
point->y = cap->y_resolution - tmp_point.y;
point->x -= 1;
point->y -= 1;
break;
case DISPLAY_ORIENTATION_ROTATED_270:
point->x = cap->x_resolution - tmp_point.y;
point->y = tmp_point.x;
point->x -= 1;
break;
default:
LOG_ERR("Invalid display orientation");
break;
}

/* filter readings within display */
if (point->x <= 0) {
point->x = 0;
} else if (point->x >= cap->x_resolution) {
point->x = cap->x_resolution - 1;
}

if (point->y <= 0) {
point->y = 0;
} else if (point->y >= cap->y_resolution) {
point->y = cap->y_resolution - 1;
}

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 Down
17 changes: 17 additions & 0 deletions modules/lvgl/lvgl_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,23 @@ int lvgl_reload_display_capabilities(void)

display_get_capabilities(disp_data->display_dev, &disp_data->cap);

switch (disp_data->cap.current_orientation) {
case DISPLAY_ORIENTATION_NORMAL:
disp->driver->rotated = LV_DISP_ROT_NONE;
break;
case DISPLAY_ORIENTATION_ROTATED_90:
disp->driver->rotated = LV_DISP_ROT_90;
break;
case DISPLAY_ORIENTATION_ROTATED_180:
disp->driver->rotated = LV_DISP_ROT_180;
break;
case DISPLAY_ORIENTATION_ROTATED_270:
disp->driver->rotated = LV_DISP_ROT_270;
break;
default:
return -EINVAL;
}

disp = lv_disp_get_next(disp);
}

Expand Down

0 comments on commit 5d1112b

Please sign in to comment.