我尝试使用lvgl来实现一个图形界面的程序,现在UI可以显示在屏幕上,但是触摸屏没有反应。
我用的触摸芯片是GT911,我使用evtest或者ts_print都能读取到触摸屏的信息,但是lvgl应用却似乎没有调用evdev_read()。下面是我用evtest的输出:
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0: rk805 pwrkey
/dev/input/event1: goodix-ts
/dev/input/event2: adc-keys
/dev/input/event3: Rmoncam A2 1080P: RMONCAM A2 10
Select the device event number [0-3]: 1
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0xdead product 0xbeef version 0x28bb
Input device name: "goodix-ts"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 48 (ABS_MT_TOUCH_MAJOR)
Value 0
Min 0
Max 255
Event code 50 (ABS_MT_WIDTH_MAJOR)
Value 0
Min 0
Max 255
Event code 53 (ABS_MT_POSITION_X)
Value 0
Min 0
Max 800
Event code 54 (ABS_MT_POSITION_Y)
Value 0
Min 0
Max 1280
Event code 57 (ABS_MT_TRACKING_ID)
Value 0
Min 0
Max 255
Properties:
Property type 1 (INPUT_PROP_DIRECT)
Testing ... (interrupt to exit)
Event: time 1501847472.953342, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1501847472.953342, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 195
Event: time 1501847472.953342, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 92
Event: time 1501847472.953342, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 26
Event: time 1501847472.953342, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 26
Event: time 1501847472.953342, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 0
Event: time 1501847472.953342, ++++++++++++++ SYN_MT_REPORT ++++++++++++
Event: time 1501847472.953342, -------------- SYN_REPORT ------------
Event: time 1501847472.964185, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 195
Event: time 1501847472.964185, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 92
Event: time 1501847472.964185, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 26
Event: time 1501847472.964185, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 26
Event: time 1501847472.964185, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 0
Event: time 1501847472.964185, ++++++++++++++ SYN_MT_REPORT ++++++++++++
Event: time 1501847472.964185, -------------- SYN_REPORT ------------
Event: time 1501847472.974098, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 195
Event: time 1501847472.974098, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 92
Event: time 1501847472.974098, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 26
Event: time 1501847472.974098, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 26
Event: time 1501847472.974098, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 0
Event: time 1501847472.974098, ++++++++++++++ SYN_MT_REPORT ++++++++++++
Event: time 1501847472.974098, -------------- SYN_REPORT ------------
Event: time 1501847472.984269, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 195
Event: time 1501847472.984269, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 92
Event: time 1501847472.984269, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 26
Event: time 1501847472.984269, type 3 (EV_ABS), code 50 (ABS_MT_WIDTH_MAJOR), value 26
Event: time 1501847472.984269, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 0
Event: time 1501847472.984269, ++++++++++++++ SYN_MT_REPORT ++++++++++++
Event: time 1501847472.984269, -------------- SYN_REPORT ------------
Event: time 1501847472.994804, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1501847472.994804, -------------- SYN_REPORT ------------
对于lvgl程序,我在lv_drv_conf.h中启用了如下内容:
# define USE_EVDEV 1
# define EVDEV_NAME "/dev/input/event1"
下面是我的主函数,以及evdev_read()函数。
int main(void)
{
// DRM_Init();
// pthread_t pth_capt;
// pthread_create(&pth_capt, NULL, (void*)V4L2_SP_Streaming, NULL);
#if 1
/* ================ */
/* ===== LVGL ===== */
/* ================ */
/*LittlevGL init*/
lv_init();
/*Linux frame buffer device init*/
drm_init();
/*A small buffer for LittlevGL to draw the screen's content*/
static lv_color_t buf[DISP_BUF_SIZE], buf1[DISP_BUF_SIZE];
/*Initialize a descriptor for the buffer*/
static lv_disp_draw_buf_t disp_buf;
// lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);
lv_disp_draw_buf_init(&disp_buf, buf, buf1, DISP_BUF_SIZE);
/*Initialize and register a display driver*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &disp_buf;
disp_drv.flush_cb = drm_flush;
disp_drv.hor_res = 800;
disp_drv.ver_res = 1280;
// disp_drv.screen_transp = 1;
lv_disp_drv_register(&disp_drv);
#if 1
// trans background
lv_style_t style_scr_act;
lv_style_init(&style_scr_act);
lv_style_set_bg_opa(&style_scr_act, LV_OPA_TRANSP);
lv_obj_add_style(lv_scr_act(), &style_scr_act, 0);
// lv_disp_set_bg_opa(lv_scr_act(), LV_OPA_TRANSP);
#endif
#if 1
evdev_init();
static lv_indev_drv_t indev_drv_1;
lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
indev_drv_1.type = LV_INDEV_TYPE_POINTER;
/*This function will be called periodically (by the library) to get the mouse position and state*/
indev_drv_1.read_cb = evdev_read;
lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);
// debug
if (mouse_indev)
{
printf("register success.\n");
}
else
{
printf("register fail.\n");
}
#endif
#if 1
/*Set a cursor for the mouse*/
LV_IMG_DECLARE(mouse_cursor_icon)
lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
lv_img_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/
lv_indev_set_cursor(mouse_indev, cursor_obj); /*Connect the image object to the driver*/
#endif
mystart();
printf("Start handler\n");
/*Handle LitlevGL tasks (tickless mode)*/
while(1) {
lv_timer_handler();
usleep(5000);
}
#endif
// pthread_exit(NULL);
return 0;
}
void evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
{
struct input_event in;
printf("[DEBUG] Entered evdev_read() function...\n");
while(read(evdev_fd, &in, sizeof(struct input_event)) > 0) {
if(in.type == EV_REL) {
printf("[DEBUG] in.type == EV_REL\n");
if(in.code == REL_X)
#if EVDEV_SWAP_AXES
evdev_root_y += in.value;
#else
evdev_root_x += in.value;
#endif
else if(in.code == REL_Y)
#if EVDEV_SWAP_AXES
evdev_root_x += in.value;
#else
evdev_root_y += in.value;
#endif
} else if(in.type == EV_ABS) {
printf("[DEBUG] in.type == EV_ABS\n");
if(in.code == ABS_X)
#if EVDEV_SWAP_AXES
evdev_root_y = in.value;
#else
evdev_root_x = in.value;
#endif
else if(in.code == ABS_Y)
#if EVDEV_SWAP_AXES
evdev_root_x = in.value;
#else
evdev_root_y = in.value;
#endif
else if(in.code == ABS_MT_POSITION_X)
#if EVDEV_SWAP_AXES
evdev_root_y = in.value;
#else
evdev_root_x = in.value;
#endif
else if(in.code == ABS_MT_POSITION_Y)
#if EVDEV_SWAP_AXES
evdev_root_x = in.value;
#else
evdev_root_y = in.value;
#endif
else if(in.code == ABS_MT_TRACKING_ID) {
if(in.value == -1)
evdev_button = LV_INDEV_STATE_REL;
else if(in.value == 0)
evdev_button = LV_INDEV_STATE_PR;
}
} else if(in.type == EV_KEY) {
printf("[DEBUG] in.type == EV_KEY\n");
if(in.code == BTN_MOUSE || in.code == BTN_TOUCH) {
if(in.value == 0)
evdev_button = LV_INDEV_STATE_REL;
else if(in.value == 1)
evdev_button = LV_INDEV_STATE_PR;
} else if(drv->type == LV_INDEV_TYPE_KEYPAD) {
#if USE_XKB
data->key = xkb_process_key(in.code, in.value != 0);
#else
switch(in.code) {
case KEY_BACKSPACE:
data->key = LV_KEY_BACKSPACE;
break;
case KEY_ENTER:
data->key = LV_KEY_ENTER;
break;
case KEY_PREVIOUS:
data->key = LV_KEY_PREV;
break;
case KEY_NEXT:
data->key = LV_KEY_NEXT;
break;
case KEY_UP:
data->key = LV_KEY_UP;
break;
case KEY_LEFT:
data->key = LV_KEY_LEFT;
break;
case KEY_RIGHT:
data->key = LV_KEY_RIGHT;
break;
case KEY_DOWN:
data->key = LV_KEY_DOWN;
break;
case KEY_TAB:
data->key = LV_KEY_NEXT;
break;
default:
data->key = 0;
break;
}
#endif /* USE_XKB */
if (data->key != 0) {
/* Only record button state when actual output is produced to prevent widgets from refreshing */
data->state = (in.value) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
}
evdev_key_val = data->key;
evdev_button = data->state;
return;
}
}
}
if(drv->type == LV_INDEV_TYPE_KEYPAD) {
/* No data retrieved */
data->key = evdev_key_val;
data->state = evdev_button;
return;
}
if(drv->type != LV_INDEV_TYPE_POINTER)
return ;
/*Store the collected data*/
#if EVDEV_CALIBRATE
data->point.x = map(evdev_root_x, EVDEV_HOR_MIN, EVDEV_HOR_MAX, 0, drv->disp->driver->hor_res);
data->point.y = map(evdev_root_y, EVDEV_VER_MIN, EVDEV_VER_MAX, 0, drv->disp->driver->ver_res);
#else
data->point.x = evdev_root_x;
data->point.y = evdev_root_y;
#endif
// debug
printf("[DEBUG] evdev_root_x: %d\n", evdev_root_x);
printf("[DEBUG] evdev_root_y: %d\n", evdev_root_y);
printf("[DEBUG] evdev_button: %d\n", evdev_button);
data->state = evdev_button;
if(data->point.x < 0)
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;
printf("[DEBUG] Leaving evdev_read() function...\n");
return ;
}
通过打印信息可以确定,程序进入了handler循环,并且没有挂掉。但是evdev_read()函数中的调试信息没有被打印,我尝试了触摸屏和鼠标,均不能使其被调用。我参考了github上的一个问题,该用户使用了/dev/input/touchscreen0替换/event2,并且解决了该问题。但是我这边只有如下的设备:
by-id by-path event0 event1 event2 event3 mice
我使用的kernel版本是4.19,lvgl版本为8.3。我不确定是否时程序对evdev的初始化出现了问题。
感谢您的回复。
离线
我克隆了`lv_port_linux_frame_buffer`,并且重新配置了项目。问题已经解决。
离线