Linux fb, indev/evdev problem with lv_display_set_rotation / screen rotation

Description

With master branch LVGL 9.1.1, SHA ID ac576a2bf4e00c7278fcbd3e704d997536eac508

I am testing lv_display_set_rotation with Raspberry Pi and Linux fb and found an issue and also managed to find a workaround with indev/evdev. This only seems to be a problem once lv_display_set_rotation is called, In my case to be 180 degrees, but I am guessing a problem will occur with any rotation other than 0 degrees.

Please see the code and explanations below.

What MCU/Processor/Board and compiler are you using?

Raspberry Pi 5 with official 7" touch screen running Raspberry Pi OS 64 - Bookworm.

What do you want to achieve?

To have the issue resolved without the need for a workaround.

Code to reproduce


#define POINT_CORRECTION 1
#define CALIBRATION_SET  1

static lv_indev_read_cb_t _indev_read_cb;

static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data)
{
    _indev_read_cb(indev, data);

#if POINT_CORRECTION
    data->point.x -= 800;
    data->point.y -= 480;
#endif

    static lv_point_t point_prev = {.x = -1, .y = -1};
    if(data->state == LV_INDEV_STATE_PRESSED) {
        if(memcmp(&point_prev, &data->point, sizeof(point_prev))) {
            point_prev = data->point;
            char buf[64];
            sprintf(buf, "x=%3u;y=%3u", data->point.x, data->point.y);
            const char * fn    = __FILE__;
            const char * slash = strrchr(fn, '/');
            fn                 = slash ? slash + 1 : fn;
            printf("%5s: %15s %4d, %20s, %s\n", "Dbg", fn, __LINE__, "Click", buf);
        }
    } else {
        point_prev.x = -1;
        point_prev.y = -1;
    }
}

int main(void)
{
    lv_init();

    lv_display_t * disp = lv_linux_fbdev_create();
    lv_linux_fbdev_set_file(disp, "/dev/fb0");
    lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_180);

    lv_indev_t * indev = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event1");
#if CALIBRATION_SET
    lv_evdev_set_calibration(indev, 0, 0, 799, 479);
#endif
    _indev_read_cb = lv_indev_get_read_cb(indev);
    lv_indev_set_read_cb(indev, _evdev_read);

    lv_demo_widgets();
    
    for(uint32_t ms;;) {
        ms = lv_timer_handler();
        usleep(ms*1000);
    }

    return 0;
}

Dump when running In each case below and touching the display in the center,

With POINT_CORRECTION = 0 and CALIBRATION_SET = 0

[Warn]  (2064886.584, +0)        indev_pointer_proc: Y is -1 which is smaller than zero lv_indev.c:654
[Warn]  (2064886.617, +33)       indev_pointer_proc: X is -1 which is smaller than zero lv_indev.c:648
[Warn]  (2064886.617, +0)        indev_pointer_proc: Y is -1 which is smaller than zero lv_indev.c:654
  Dbg:          main.c  172,                Click, x=800;y=480
[Warn]  (2064886.650, +33)       indev_pointer_proc: X is -1 which is smaller than zero lv_indev.c:648
[Warn]  (2064886.650, +0)        indev_pointer_proc: Y is -1 which is smaller than zero lv_indev.c:654
[Warn]  (2064886.683, +33)       indev_pointer_proc: X is -1 which is smaller than zero lv_indev.c:648

With POINT_CORRECTION = 1 and CALIBRATION_SET = 0

 Dbg:          main.c  172,                Click, x=  0;y=  0

With POINT_CORRECTION = 1 and CALIBRATION_SET = 1

  Dbg:          main.c  172,                Click, x=449;y=257
  Dbg:          main.c  172,                Click, x=449;y=256
  Dbg:          main.c  172,                Click, x=448;y=253

So correcting the point by subtracting the displays horizontal and vertical resolutions from the point coords solves the problem but only if lv_evdev_set_calibration has also been called as above. Ideally this will be solved without the need for a workaround.

I hope this helps and look forward to a solution.