lvgl / lv_port_linux

LVGL configured to work with a standard Linux framebuffer
MIT License
260 stars 160 forks source link

touch event support not working #9

Closed embetrix closed 3 years ago

embetrix commented 3 years ago

Hello,

I built this demo for rpi3 with official 7-inch display with resolution : 800x480

I first adapted the resolution:

diff --git a/lv_conf.h b/lv_conf.h
index b31a820..414de25 100644
--- a/lv_conf.h
+++ b/lv_conf.h
@@ -20,8 +20,8 @@
  *====================*/

 /* Maximal horizontal and vertical resolution to support by the library.*/
-#define LV_HOR_RES_MAX          (480)
-#define LV_VER_RES_MAX          (320)
+#define LV_HOR_RES_MAX          (800)
+#define LV_VER_RES_MAX          (480)

 /* Color depth:
  * - 1:  1 byte per pixel

the I enabled the input events:

diff --git a/lv_drv_conf.h b/lv_drv_conf.h
index 975c7b4..8e06825 100644
--- a/lv_drv_conf.h
+++ b/lv_drv_conf.h
@@ -310,7 +310,7 @@
  * Touchscreen as libinput interface (for Linux based systems)
  *------------------------------------------------*/
 #ifndef USE_LIBINPUT
-#  define USE_LIBINPUT           0
+#  define USE_LIBINPUT           1
 #endif

 #if USE_LIBINPUT
@@ -321,7 +321,7 @@
  * Mouse or touchpad as evdev interface (for Linux based systems)
  *------------------------------------------------*/
 #ifndef USE_EVDEV
-#  define USE_EVDEV           0
+#  define USE_EVDEV           1
 #endif

 #if USE_EVDEV

I also mad sure that demo is linked against libinput by adding -linput to the Makefile.

The demo is showing up and running but not touch event are detected !

My touch is attached to /dev/input/event0

root@raspberrypi3:~# evemu-describe 
Available devices:
/dev/input/event0:      raspberrypi-ts

any hints how to enable the touch or how top debug this issue ?

embeddedt commented 3 years ago

Have you called evdev_init and registered an lv_indev_drv_t structure?

embetrix commented 3 years ago

No do you have an example to show that ? I assumed that the port for Linux does provide it! otherwise how would be the UI tested ?

embeddedt commented 3 years ago

Here is an example:

https://forum.lvgl.io/t/lvgl-port-for-linux-framebuffer-in-beaglebone-black-with-debian-buster/2674/16?u=embeddedt

By default, the Linux port only enables the display, as not all devices it gets used on have a touchscreen.

embetrix commented 3 years ago

@embeddedt: I will try that, thanks

embetrix commented 3 years ago

@embeddedt I tried and it's working however it seems to have some issues: when I use Text input whenever I click on ONE letter I see it's double in the Text field

example: I want to enter lvgl Text Input is getting: llvvggll I don't know if it's a bug in the events driver or Text input ?

the check box does not get checked

embeddedt commented 3 years ago

Can you send the output of evtest /dev/input/event0 with markings for when you press and release? I'd like to compare it to what the driver expects. It's possible your touchscreen sends the events a bit differently.

embetrix commented 3 years ago

@embeddedt : the touch is the official rpi 7 inch display it works fine with other GUIs such as Qt5:

here is a snippet of evemu-record when touching the virtual keyboard once to enter a single letter 'a' :

root@raspberrypi3:~# evemu-record /dev/input/event0 
# EVEMU 1.3
# Kernel: 5.10.17-v7
# Input device name: "raspberrypi-ts"
# Input device ID: bus 0x19 vendor 0000 product 0000 version 0000
# Supported events:
#   Event type 0 (EV_SYN)
#     Event code 0 (SYN_REPORT)
#     Event code 1 (SYN_CONFIG)
#     Event code 2 (SYN_MT_REPORT)
#     Event code 3 (SYN_DROPPED)
#     Event code 4 ((null))
#     Event code 5 ((null))
#     Event code 6 ((null))
#     Event code 7 ((null))
#     Event code 8 ((null))
#     Event code 9 ((null))
#     Event code 10 ((null))
#     Event code 11 ((null))
#     Event code 12 ((null))
#     Event code 13 ((null))
#     Event code 14 ((null))
#     Event code 15 (SYN_MAX)
#   Event type 1 (EV_KEY)
#     Event code 330 (BTN_TOUCH)
#   Event type 3 (EV_ABS)
#     Event code 0 (ABS_X)
#       Value      146
#       Min          0
#       Max        799
#       Fuzz         0
#       Flat         0
#       Resolution   0
#     Event code 1 (ABS_Y)
#       Value      338
#       Min          0
#       Max        479
#       Fuzz         0
#       Flat         0
#       Resolution   0
#     Event code 47 (ABS_MT_SLOT)
#       Value        0
#       Min          0
#       Max          9
#       Fuzz         0
#       Flat         0
#       Resolution   0
#     Event code 53 (ABS_MT_POSITION_X)
#       Value        0
#       Min          0
#       Max        799
#       Fuzz         0
#       Flat         0
#       Resolution   0
#     Event code 54 (ABS_MT_POSITION_Y)
#       Value        0
#       Min          0
#       Max        479
#       Fuzz         0
#       Flat         0
#       Resolution   0
#     Event code 57 (ABS_MT_TRACKING_ID)
#       Value        0
#       Min          0
#       Max      65535
#       Fuzz         0
#       Flat         0
#       Resolution   0
# Properties:
#   Property  type 1 (INPUT_PROP_DIRECT)
N: raspberrypi-ts
I: 0019 0000 0000 0000
P: 02 00 00 00 00 00 00 00
B: 00 0b 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 04 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 01 00 00 00 00 00 00 00 00
B: 02 00 00 00 00 00 00 00 00
B: 03 03 00 00 00 00 80 60 02
B: 04 00 00 00 00 00 00 00 00
B: 05 00 00 00 00 00 00 00 00
B: 11 00 00 00 00 00 00 00 00
B: 12 00 00 00 00 00 00 00 00
B: 14 00 00 00 00 00 00 00 00
B: 15 00 00 00 00 00 00 00 00
B: 15 00 00 00 00 00 00 00 00
A: 00 0 799 0 0 0
A: 01 0 479 0 0 0
A: 2f 0 9 0 0 0
A: 35 0 799 0 0 0
A: 36 0 479 0 0 0
A: 39 0 65535 0 0 0
################################
#      Waiting for events      #
################################
E: 0.000001 0003 0039 0005  # EV_ABS / ABS_MT_TRACKING_ID   5
E: 0.000001 0003 0035 0233  # EV_ABS / ABS_MT_POSITION_X    233
E: 0.000001 0003 0036 0279  # EV_ABS / ABS_MT_POSITION_Y    279
E: 0.000001 0001 014a 0001  # EV_KEY / BTN_TOUCH            1
E: 0.000001 0003 0000 0233  # EV_ABS / ABS_X                233
E: 0.000001 0003 0001 0279  # EV_ABS / ABS_Y                279
E: 0.000001 0000 0000 0000  # ------------ SYN_REPORT (0) ---------- +0ms
E: 0.059997 0003 0039 -001  # EV_ABS / ABS_MT_TRACKING_ID   -1
E: 0.059997 0001 014a 0000  # EV_KEY / BTN_TOUCH            0
E: 0.059997 0000 0000 0000  # ------------ SYN_REPORT (0) ---------- +59ms

this looks fine but the input text shows 'aa', this is defintely a BUG in lvgl or the lvgl touch driver.

embetrix commented 3 years ago

furthermore the check box is also buggy and does not get checked : screen

embetrix commented 3 years ago

Dark Mode Selector doesn't work neither: screen1

embetrix commented 3 years ago

Dropdown selector doesn't seems to work!

embeddedt commented 3 years ago

Hmm... can you add a printf on this line of evdev.c which prints data->state, data->point.x, and data->point.y? I read the evdev_read function and compared it to your event log but I can't see exactly where it's failing.

embetrix commented 3 years ago

I modified evdev.c

diff --git a/indev/evdev.c b/indev/evdev.c
index df3cbd6..32a1798 100644
--- a/indev/evdev.c
+++ b/indev/evdev.c
@@ -205,6 +205,8 @@ bool evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
     if(data->point.y >= lv_disp_get_ver_res(drv->disp))
       data->point.y = lv_disp_get_ver_res(drv->disp) - 1;

+    if(data->state)
+      printf("data->state:%d data->point.x:%d data->point.y:%d \n", data->state, data->point.x, data->point.y);
     return false;
 }

here is the output on single touch event:

data->state:1 data->point.x:547 data->point.y:393 
data->state:1 data->point.x:547 data->point.y:393 
data->state:1 data->point.x:547 data->point.y:393 
data->state:1 data->point.x:547 data->point.y:393 
data->state:1 data->point.x:547 data->point.y:393 
data->state:1 data->point.x:547 data->point.y:393

it looks like the event is registerd x6 times

embeddedt commented 3 years ago

That behavior looks correct to me. Until data->state changes back to 0, LVGL will just see that as the finger being held down. Do you see it rapidly alternating between 0 and 1 at the moment you press/release?

@kisvegabor Any other ideas?

embetrix commented 3 years ago

Looks like I'm not the only one experiencing this issue: https://github.com/lvgl/lvgl/issues/2274

kisvegabor commented 3 years ago

Please remove the if(data->state) to log released reads too and add lv_tick_get():

  printf("%dms\tstate:%d\tx:%d\ty:%d\n", lv_tick_get(), data->state, data->point.x, data->point.y);
embetrix commented 3 years ago

@kisvegabor this is a log on one touch event :

4696ms  state:0 x:491   y:135
4697ms  state:0 x:491   y:135
4798ms  state:0 x:491   y:135
4798ms  state:0 x:491   y:135
4898ms  state:0 x:491   y:135
4898ms  state:0 x:491   y:135
4999ms  state:0 x:491   y:135
4999ms  state:0 x:491   y:135
5100ms  state:0 x:491   y:135
5100ms  state:0 x:491   y:135
5201ms  state:0 x:491   y:135
5201ms  state:0 x:491   y:135
5301ms  state:1 x:277   y:320
5302ms  state:1 x:277   y:320
5409ms  state:1 x:277   y:320
5410ms  state:1 x:277   y:320
5510ms  state:0 x:277   y:320
5510ms  state:0 x:277   y:320
5617ms  state:0 x:277   y:320
5618ms  state:0 x:277   y:320
5719ms  state:0 x:277   y:320
5719ms  state:0 x:277   y:320
5819ms  state:0 x:277   y:320
5819ms  state:0 x:277   y:320
5920ms  state:0 x:277   y:320
5920ms  state:0 x:277   y:320

it seems to be triggered multiple times!

kisvegabor commented 3 years ago

Are you sure the orientation of the touch screen is correct?

You can add a mouse cursor to see where the touch is recognized.

embetrix commented 3 years ago

I have set lcd_rotate = 2 (180 degree rotation) but when setting to original lcd_rotate = 0 ( no rotation) I get the same results

kisvegabor commented 3 years ago

Please add the mouse cursor as I suggested to clearly see what happens.

embetrix commented 3 years ago

@kisvegabor

it does not build with lv_port_linux_frame_buffer:

main.c: In function ‘main’:
main.c:48:29: error: too few arguments to function ‘lv_img_create’
   48 |     lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
      |                             ^~~~~~~~~~~~~
In file included from lvgl/lvgl.h:39,
                 from main.c:1:
lvgl/src/lv_widgets/lv_img.h:65:12: note: declared here
   65 | lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy);
      |            ^~~~~~~~~~~~~
main.c:50:25: error: ‘mouse_indev’ undeclared (first use in this function)
   50 |     lv_indev_set_cursor(mouse_indev, cursor_obj);             /*Connect the image  object to the driver*/
      |                         ^~~~~~~~~~~
main.c:50:25: note: each undeclared identifier is reported only once for each function it appears in
main.c: At top level:
kisvegabor commented 3 years ago

Try this: https://github.com/lvgl/lv_sim_eclipse_sdl/blob/10bdd7e10352402596ea2e5b58671bffc49fe5b1/main.c#L111-L114 The previous was for LVGL v8 and this is for v7.

For mosue_indev use the return value of lv_indev_register.

embetrix commented 3 years ago

got the follwoing link error:

main.c:(.text.startup+0xc8): undefined reference to `mouse_cursor_icon'
collect2: error: ld returned 1 exit status
Makefile:38: recipe for target 'default' failed
embetrix commented 3 years ago

@kisvegabor : would be also possible to update lv_port_linux_frame_buffer to LVGL v8 ?

kisvegabor commented 3 years ago

got the follwoing link error:

mouse_cursor_icon is here.

would be also possible to update lv_port_linux_frame_buffer to LVGL v8 ?

I've updated it a week ago.

embetrix commented 3 years ago

the V8 does not even build !

 /home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/wayland/wayland.c
CC /home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/mousewheel.c
CC /home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/AD_touch.c
CC /home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/mouse.c
/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/libinput.c:47:1: warning: ‘static’ is not at beginning of declaration [-Wold-style-declaration]
 const static struct libinput_interface interface = {
 ^~~~~
CC /home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/libinput.c
/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/evdev.c: In function ‘evdev_read’:
/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/evdev.c:161:20: warning: suggest explicit braces to avoid ambiguous ‘else’ [-Wdangling-else]
             else if(in.code == ABS_MT_TRACKING_ID)
                    ^
/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/evdev.c:228:42: error: ‘drv->disp->driver’ is a pointer; did you mean to use ‘->’?
     if(data->point.x >= drv->disp->driver.hor_res)
                                          ^
                                          ->
/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/evdev.c:229:40: error: ‘drv->disp->driver’ is a pointer; did you mean to use ‘->’?
       data->point.x = drv->disp->driver.hor_res - 1;
                                        ^
                                        ->
/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/evdev.c:230:42: error: ‘drv->disp->driver’ is a pointer; did you mean to use ‘->’?
     if(data->point.y >= drv->disp->driver.ver_res)
                                          ^
                                          ->
/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/evdev.c:231:40: error: ‘drv->disp->driver’ is a pointer; did you mean to use ‘->’?
       data->point.y = drv->disp->driver.ver_res - 1;
                                        ^
                                        ->
Makefile:34: recipe for target '/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/evdev.o' failed
make: *** [/home/zaki/Workspace/Playground/lv_port_linux_frame_buffer/lv_drivers/indev/evdev.o] Error 1
embetrix commented 3 years ago

This should help:

diff --git a/indev/evdev.c b/indev/evdev.c
index 975a479..e85b7f4 100644
--- a/indev/evdev.c
+++ b/indev/evdev.c
@@ -225,10 +225,10 @@ bool evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
       data->point.x = 0;
     if(data->point.y < 0)
       data->point.y = 0;
-    if(data->point.x >= drv->disp->driver.hor_res)
-      data->point.x = drv->disp->driver.hor_res - 1;
-    if(data->point.y >= drv->disp->driver.ver_res)
-      data->point.y = drv->disp->driver.ver_res - 1;
+    if(data->point.x >= drv->disp->driver->hor_res)
+      data->point.x = drv->disp->driver->hor_res - 1;
+    if(data->point.y >= drv->disp->driver->ver_res)
+      data->point.y = drv->disp->driver->ver_res - 1;

     return false;
 }
kisvegabor commented 3 years ago

I merged your PR, thanks.

Finally, could you add the mouse cursor?

embetrix commented 3 years ago

I have found the issue, had a typo with lv_indev_drv_register twice !

+    /*Initialize and register an input device*/
+    static lv_indev_drv_t indev_drv;
+    lv_indev_drv_init(&indev_drv);
+    indev_drv.type = LV_INDEV_TYPE_POINTER;
+    indev_drv.read_cb = evdev_read;
+    lv_indev_drv_register(&indev_drv);
+    lv_indev_drv_register(&indev_drv);

Please update the submodule of lv_drivers to the new one and we can close this issue.

Thanks for your support

kisvegabor commented 3 years ago

I have found the issue, had a typo with lv_indev_drv_register twice !

Ah, great that you have found it.

I've updated the submodules of this repo.