haltest: fix haltest ro run properly
authorduna.oh <duna.oh@samsung.com>
Tue, 14 Feb 2023 08:37:36 +0000 (17:37 +0900)
committerduna.oh <duna.oh@samsung.com>
Fri, 24 Feb 2023 06:08:12 +0000 (15:08 +0900)
- keyboard devices can have either ID_INPUT_KEY OR ID_INPUT_KEYBOARD
- keyboard_events
  : retrieve which keycode is available for the device and
  generate key event using available keycode
- touch_events
  : retrieve the ABS_MT_POSITION's resolution/max data from the device and
  validate touch events using these data

haltests/meson.build
haltests/test_hal_libinput_info.cpp
haltests/test_hal_libinput_info.h
haltests/test_hal_libinput_mtdev_check.cpp
haltests/test_hal_libinput_mtdev_check.h
meson.build
packaging/libinput.spec

index 2ebe3c6..8e8c406 100644 (file)
@@ -22,5 +22,6 @@ executable(
     dependencies : [ deps_litest, gmock_dep ],
     include_directories : [ libinput_haltests_include_dirs, includes_include, includes_src ],
     install_dir : bindir_hal,
+    cpp_args : '-Wno-unused-parameter',
     install : true
 )
index 5ddbe48..94fa76f 100644 (file)
@@ -6,6 +6,7 @@
 #include <libevdev/libevdev.h>
 #include <libevdev/libevdev-uinput.h>
 
+
 static const uint32_t screen_width = 100;
 static const uint32_t screen_height = 100;
 
@@ -23,6 +24,33 @@ static bool evdev_bit_is_set(const unsigned long *array, int bit)
     return array[bit / LONG_BIT] & (1LL << (bit % LONG_BIT));
 }
 
+static const char * const absval[6] = { "Value", "Min  ", "Max  ", "Fuzz ", "Flat ", "Resolution "};
+
+static void print_absdata(struct record_device *d, int fd, int axis)
+{
+       int abs[6] = {0};
+       int k;
+
+       ioctl(fd, EVIOCGABS(axis), abs);
+       for (k = 0; k < 6; k++) {
+               if ((k < 3) || abs[k]) {
+                       LOG("      %s %6d\n", absval[k], abs[k]);
+                       if (k == 2) {
+                               if (axis == ABS_MT_POSITION_X)
+                                       d->abs_max_x = abs[k];
+                               else if (axis == ABS_MT_POSITION_Y)
+                                       d->abs_max_y = abs[k];
+                       }
+                       else if (k == 5) {
+                               if (axis == ABS_MT_POSITION_X)
+                                       d->abs_resolution_x = abs[k];
+                               else if (axis == ABS_MT_POSITION_Y)
+                                       d->abs_resolution_y = abs[k];
+                       }
+               }
+       }
+}
+
 int handle_device_notify(struct libinput_event *ev)
 {
        struct libinput_device *dev = libinput_event_get_device(ev);
@@ -30,6 +58,7 @@ int handle_device_notify(struct libinput_event *ev)
        enum libinput_event_type type;
        const char *devnode;
        const char *test = NULL;
+       const char *test1 = NULL;
        errno = 0;
 
        switch(libinput_event_get_type(ev)) {
@@ -45,7 +74,8 @@ int handle_device_notify(struct libinput_event *ev)
 
        test = udev_device_get_property_value(udev_device, "DEVPATH");
        if(test && strstr(test, "virtual")){
-               LOG("It's contain virtual. No Check.\n");
+               devnode = udev_device_get_devnode(libinput_device_get_udev_device(dev));
+               LOG("It contains virtual. No Check. (devnode = %s)\n", devnode);
                return 0;
        }
 
@@ -53,11 +83,13 @@ int handle_device_notify(struct libinput_event *ev)
                devnode = udev_device_get_devnode(libinput_device_get_udev_device(dev));
                if(type == LIBINPUT_EVENT_DEVICE_ADDED) { // TODO. save using linked list
                        test = udev_device_get_property_value(udev_device, "ID_INPUT_KEYBOARD");
+                       test1 = udev_device_get_property_value(udev_device, "ID_INPUT_KEY");
                        LOG("devnode = %s\n", devnode);
-                       if(test && (test[0] == '1')){
-                               LOG("ID_INPUT_KEYBOARD test = %s\n", test);
+                       if((test && (test[0] == '1')) ||
+                          (test1 && (test1[0] == '1'))) {
+                               LOG("ID_INPUT_KEYBOARD(_KEY) test = 1\n");
                                devices[devices_cnt].cap = LIBINPUT_DEVICE_CAP_KEYBOARD;
-                               devices[devices_cnt++].path = devnode;
+                               devices[devices_cnt].path = devnode;
                                int fd = open(devnode, O_RDWR);
                                if (fd < 0) {
                                        LOGE("ERROR: %m\n");
@@ -66,14 +98,18 @@ int handle_device_notify(struct libinput_event *ev)
                                unsigned long evbits[NLONGS(EV_CNT)] = { 0 };
                                ioctl(fd, EVIOCGBIT(0, sizeof(evbits)), evbits);
                                if (!evdev_bit_is_set(evbits, EV_KEY))
-                                       LOG("no evdev bit is set\n");
+                                       LOG("no 'EV_KEY' bit is set\n");
                                unsigned long keybits[NLONGS(KEY_CNT)] = { 0 };
                                ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
-                               for(int i = KEY_RESERVED; i< KEY_MIN_INTERESTING; ++i)
+                               for(int i = KEY_RESERVED; i< KEY_MAX; ++i)
                                        if(evdev_bit_is_set(keybits, i)){
+                                               LOG("Event Code %d\n", i);
+                                               devices[devices_cnt].available_keycode = i;
                                                break;
                                        }
                                close(fd);
+
+                               devices_cnt++;
                        }
                }
        }
@@ -99,7 +135,34 @@ int handle_device_notify(struct libinput_event *ev)
                        if(test && (test[0] == '1')){
                                LOG("ID_INPUT_TOUCHSCREEN test = %s\n", test);
                                devices[devices_cnt].cap = LIBINPUT_DEVICE_CAP_TOUCH;
-                               devices[devices_cnt++].path = devnode;
+                               devices[devices_cnt].path = devnode;
+
+                               int fd = open(devnode, O_RDWR);
+                               unsigned int code;
+                               if (fd < 0) {
+                                       LOGE("ERROR: %m\n");
+                                       return -1;
+                               }
+                               unsigned long evbits[NLONGS(EV_CNT)] = { 0 };
+                               ioctl(fd, EVIOCGBIT(0, sizeof(evbits)), evbits);
+                               if (!evdev_bit_is_set(evbits, EV_ABS))
+                                       LOG("no 'EV_ABS' evdev bit is set\n");
+
+                               unsigned long keybits[NLONGS(KEY_CNT)] = { 0 };
+                               ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(keybits)), keybits);
+                               code = ABS_MT_POSITION_X;
+                               if(evdev_bit_is_set(keybits, code)){
+                                       LOG("Event Code %d\n", code);
+                                       print_absdata(&(devices[devices_cnt]), fd, code);
+                               }
+                               code = ABS_MT_POSITION_Y;
+                               if(evdev_bit_is_set(keybits, code)){
+                                       LOG("Event Code %d\n", code);
+                                       print_absdata(&(devices[devices_cnt]), fd, code);
+                               }
+                               close(fd);
+
+                               devices_cnt++;
                        }
                }
        }
@@ -152,11 +215,11 @@ handle_motion_event(struct libinput_event *ev)
 
        if(queue_record_event[pop_idx].p.event_type != type) return -1;
        if(queue_record_event[pop_idx].p.x != (int)ux) return -1;
-       if(queue_record_event[pop_idx].p.x != (int)uy) return -1;
+       if(queue_record_event[pop_idx].p.y != (int)uy) return -1;
 
        EXPECT_EQ(queue_record_event[pop_idx].p.event_type, type);
        EXPECT_EQ(queue_record_event[pop_idx].p.x, (int)ux);
-       EXPECT_EQ(queue_record_event[pop_idx].p.x, (int)uy);
+       EXPECT_EQ(queue_record_event[pop_idx].p.y, (int)uy);
 
        return 0;
 }
@@ -347,16 +410,27 @@ handle_touch_event(struct libinput_event *ev)
        case LIBINPUT_EVENT_TOUCH_MOTION:
                x = libinput_event_touch_get_x(t);
                y = libinput_event_touch_get_y(t);
-               tx = libinput_event_touch_get_x_transformed(t, 100);
-               ty = libinput_event_touch_get_y_transformed(t, 100);
+               tx = libinput_event_touch_get_x_transformed(t, screen_width);
+               ty = libinput_event_touch_get_y_transformed(t, screen_height);
                LOG("type: %s, slot: %d, seat_slot: %d, point: [%6.2f, %6.2f], transformed: [%6.2f, %6.2f]\n",
                         type, slot, seat_slot, x, y, tx, ty);
-               LOG("type = %d, slot : %d, x = %d, y = %d, state = %d\n", queue_record_event[pop_idx].t.event_type, queue_record_event[pop_idx].t.idx, queue_record_event[pop_idx].t.x,
-                                       queue_record_event[pop_idx].t.y, queue_record_event[pop_idx].t.state);
+
+               queue_record_event[pop_idx].t.transformed_x *= screen_width;
+               queue_record_event[pop_idx].t.transformed_y *= screen_height;
+
+               LOG("recorded event: type = %d, slot : %d, point: [%6.2f, %6.2f], transformed: [%6.2f, %6.2f], state = %d\n",
+                       queue_record_event[pop_idx].t.event_type, queue_record_event[pop_idx].t.idx,
+                       queue_record_event[pop_idx].t.res_x, queue_record_event[pop_idx].t.res_y,
+                       queue_record_event[pop_idx].t.transformed_x, queue_record_event[pop_idx].t.transformed_y,
+                       queue_record_event[pop_idx].t.state);
+
                EXPECT_EQ(queue_record_event[pop_idx].t.event_type, etype);
                EXPECT_EQ(queue_record_event[pop_idx].t.idx, (int)slot);
-               EXPECT_EQ(queue_record_event[pop_idx].t.x, (int)x);
-               EXPECT_EQ(queue_record_event[pop_idx].t.y, (int)y);
+               EXPECT_EQ((int)queue_record_event[pop_idx].t.res_x, (int)x);
+               EXPECT_EQ((int)queue_record_event[pop_idx].t.res_y, (int)y);
+
+               EXPECT_EQ((int)queue_record_event[pop_idx].t.transformed_x, (int)tx);
+               EXPECT_EQ((int)queue_record_event[pop_idx].t.transformed_y, (int)ty);
                break;
        case LIBINPUT_EVENT_TOUCH_UP:
        case LIBINPUT_EVENT_TOUCH_CANCEL:
@@ -437,13 +511,14 @@ int create_mouse_event(struct libinput *li, int idx)
        struct record_libinput_event_pointer p[] = {
                {LIBINPUT_EVENT_POINTER_BUTTON, (int) BTN_LEFT, 100, 100, 1},
                {LIBINPUT_EVENT_POINTER_MOTION, 0, 120, 120, 2},
+               {LIBINPUT_EVENT_POINTER_MOTION, 0, 150, 180, 2},
                {LIBINPUT_EVENT_POINTER_BUTTON, (int) BTN_LEFT, 200, 200, 0}
        };
        struct record_libinput_event_keyboard k = {LIBINPUT_EVENT_NONE, 0, 0};
-       struct record_libinput_event_touch t = {LIBINPUT_EVENT_NONE, 0, 0, 0, 0};
+       struct record_libinput_event_touch t = {LIBINPUT_EVENT_NONE, 0, 0, 0, 0, 0, 0, 0, 0};
 
        if(devices[idx].cap == LIBINPUT_DEVICE_CAP_POINTER){
-               LOG("create_mouse_event\n");
+               LOG("create_mouse_event (path: %s)\n", devices[idx].path);
                fd = open(devices[idx].path, O_RDWR);
                if (fd < 0) {
                        LOGE("ERROR: could not open device. %m\n");
@@ -481,16 +556,14 @@ int create_keyboard_event(struct libinput *li, int idx)
 
        struct record_event rc_e;
        struct record_libinput_event_keyboard k[] = {
-               {LIBINPUT_EVENT_KEYBOARD_KEY, 1, 1},  // keycode 1, press
-               {LIBINPUT_EVENT_KEYBOARD_KEY, 1, 0},   // keycode 1, release
-               {LIBINPUT_EVENT_KEYBOARD_KEY, KEY_A, 1},  // keycode KEY_A, press
-               {LIBINPUT_EVENT_KEYBOARD_KEY, KEY_A, 0},   // keycode KEY_A, release
+               {LIBINPUT_EVENT_KEYBOARD_KEY, devices[idx].available_keycode, 1},  // available_keycode, press
+               {LIBINPUT_EVENT_KEYBOARD_KEY, devices[idx].available_keycode, 0},  // available_keycode, release
        };
        struct record_libinput_event_pointer p = {LIBINPUT_EVENT_NONE, 0, 0, 0, 0};
-       struct record_libinput_event_touch t = {LIBINPUT_EVENT_NONE, 0, 0, 0, 0};
+       struct record_libinput_event_touch t = {LIBINPUT_EVENT_NONE, 0, 0, 0, 0, 0, 0, 0, 0};
 
        if(devices[idx].cap == LIBINPUT_DEVICE_CAP_KEYBOARD){
-               LOG("create_keyboard_event\n");
+               LOG("create_keyboard_event (path: %s)\n", devices[idx].path);
                fd = open(devices[idx].path, O_RDWR);
                if (fd < 0) {
                        LOGE("ERROR: could not open device. %m\n");
@@ -537,7 +610,7 @@ int multi_touch_support(struct libinput *li, int idx)
                        LOGE("ERROR: could not grab the device. %m\n");
                        return -1;
                }
-               if (check_device_mtprops(fd) < 0) {
+               if (check_device_mt_event_codes(fd) < 0) {
                        ioctl(fd, EVIOCGRAB, 0);
                        close(fd);
                        LOGE("ERROR: NO mt must props. %m\n");
@@ -559,15 +632,15 @@ int create_touch_event(struct libinput *li, int idx)
 
        struct record_event rc_e;
        struct record_libinput_event_touch t[] = {
-               {LIBINPUT_EVENT_TOUCH_DOWN, 1, 100, 100, 1},
-               {LIBINPUT_EVENT_TOUCH_MOTION, 1, 120, 150, 2},
-               {LIBINPUT_EVENT_TOUCH_UP, 1, 120, 150, 0},
+               {LIBINPUT_EVENT_TOUCH_DOWN, 1, 100, 100, 0, 0, 0, 0, 1},
+               {LIBINPUT_EVENT_TOUCH_MOTION, 1, 120, 150, 0, 0, 0, 0, 2},
+               {LIBINPUT_EVENT_TOUCH_UP, 1, 120, 150, 0, 0, 0, 0, 0},
        };
        struct record_libinput_event_pointer p = {LIBINPUT_EVENT_NONE, 0, 0, 0, 0};
        struct record_libinput_event_keyboard k = {LIBINPUT_EVENT_NONE, 0, 0};
 
        if(devices[idx].cap == LIBINPUT_DEVICE_CAP_TOUCH){
-               LOG("create_touch_event\n");
+               LOG("create_touch_event (path: %s)\n", devices[idx].path);
                fd = open(devices[idx].path, O_RDWR);
                if (fd < 0) {
                        LOGE("ERROR: could not open device. %m\n");
@@ -578,6 +651,11 @@ int create_touch_event(struct libinput *li, int idx)
                rc_e.device = LIBINPUT_DEVICE_CAP_TOUCH;
                for(int i=0; i<n; ++i)
                {
+                       t[i].res_x = (double)t[i].x / devices[idx].abs_resolution_x;
+                       t[i].res_y = (double)t[i].y / devices[idx].abs_resolution_y;
+                       t[i].transformed_x = (double)t[i].x / devices[idx].abs_max_x;
+                       t[i].transformed_y = (double)t[i].y / devices[idx].abs_max_y;
+
                        rc_e.t = t[i];
                        rc_e.p = p;
                        rc_e.k = k;
@@ -664,7 +742,7 @@ bool validate_touch_event(struct libinput *li)
                        queue_idx = 0;
                        pop_idx = -1;
                        if(multi_touch_support(li, i) < 0) {
-                               LOG("NO MULTI TOUCH SURPPORT. dont' have to test touch\n");
+                               LOG("NO MULTI TOUCH SUPPORT. don't have to test touch\n");
                        }
                        else{
                                create_touch_event(li, i);
index c37c156..40df450 100644 (file)
@@ -47,6 +47,11 @@ bool validate_touch_event(struct libinput *li);
 struct record_device {
        enum libinput_device_capability cap;
        const char *path;
+       int available_keycode;
+       int abs_max_x;
+       int abs_max_y;
+       int abs_resolution_x;
+       int abs_resolution_y;
 };
 
 struct record_libinput_event_pointer {
@@ -68,6 +73,10 @@ struct record_libinput_event_touch {
        int idx;
        int x;
        int y;
+       double res_x;
+       double res_y;
+       double transformed_x;
+       double transformed_y;
        int32_t state; //pressed
  };
 
index 55133cf..de1773d 100644 (file)
@@ -44,14 +44,14 @@ static int check_must_have(int code)
        switch (code)
        {
                case ABS_MT_SLOT:
-               case ABS_MT_TOUCH_MAJOR:
-               case ABS_MT_TOUCH_MINOR:
                case ABS_MT_POSITION_X:
                case ABS_MT_POSITION_Y:
                case ABS_MT_TRACKING_ID:
                        ret = 0;
                        break;
 
+               case ABS_MT_TOUCH_MAJOR:
+               case ABS_MT_TOUCH_MINOR:
                case ABS_MT_WIDTH_MAJOR:
                case ABS_MT_WIDTH_MINOR:
                case ABS_MT_ORIENTATION:
@@ -114,46 +114,46 @@ static const char* print_code(int code)
        return code_str;
 }
 
-static int check_has_props(const struct mtdev *dev, int name)
+static int check_has_mt_event(const struct mtdev *dev, int name)
 {
        int ret = -1;
        if(!check_must_have(name) && mtdev_has_mt_event(dev, name)) {
-               LOG("must have && it has : %s\n", print_code(name));
+               LOG("REQUIRED to have && it has : %s\n", print_code(name));
                ret = 0;
        }
        else if (!check_must_have(name) && !mtdev_has_mt_event(dev, name)) {
-               LOGE("ERROR!! must have && it doesnt have : %s\n", print_code(name));
+               LOGE("ERROR!! REQUIRED to have && it doesn't have : %s\n", print_code(name));
                ret = -1;
        }
        else { // no must
-               LOG("don't have to : %s\n", print_code(name));
+               LOG("optional to have : %s\n", print_code(name));
                ret = 0;
        }
        return ret;
 }
 
-static int check_props(const struct mtdev *dev)
+static int check_mt_event_codes(const struct mtdev *dev)
 {
        LOG("supported mt events:\n");
 
-       if(check_has_props(dev, ABS_MT_SLOT) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_TOUCH_MAJOR) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_TOUCH_MINOR) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_WIDTH_MAJOR) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_WIDTH_MINOR) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_ORIENTATION) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_POSITION_X) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_POSITION_Y) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_TOOL_TYPE) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_BLOB_ID) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_TRACKING_ID) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_PRESSURE) < 0) return -1;
-       if(check_has_props(dev, ABS_MT_DISTANCE) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_SLOT) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_TOUCH_MAJOR) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_TOUCH_MINOR) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_WIDTH_MAJOR) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_WIDTH_MINOR) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_ORIENTATION) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_POSITION_X) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_POSITION_Y) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_TOOL_TYPE) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_BLOB_ID) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_TRACKING_ID) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_PRESSURE) < 0) return -1;
+       if(check_has_mt_event(dev, ABS_MT_DISTANCE) < 0) return -1;
 
        return 0;
 }
 
-int check_device_mtprops(int fd)
+int check_device_mt_event_codes(int fd)
 {
        int ret = -1;
        struct mtdev dev;
@@ -162,7 +162,7 @@ int check_device_mtprops(int fd)
                LOGE("ERROR! could not open device: %d\n", ret);
                return -1;
        }
-       ret = check_props(&dev);
+       ret = check_mt_event_codes(&dev);
        mtdev_close(&dev);
        return ret;
 }
index 947889b..c3cfed6 100644 (file)
@@ -13,7 +13,7 @@ extern "C" {
 #include <fcntl.h>
 #include <time.h>
 
-int check_device_mtprops(int fd);
+int check_device_mt_event_codes(int fd);
 
 #ifdef __cplusplus
 }
index e1ed023..1ae595d 100644 (file)
@@ -331,9 +331,9 @@ libinput_data_override_path = dir_overrides / 'local-overrides.quirks'
 config_h.set_quoted('LIBINPUT_QUIRKS_DIR', dir_data)
 config_h.set_quoted('LIBINPUT_QUIRKS_OVERRIDE_FILE', libinput_data_override_path)
 
-if get_option('quirks-enable')
 
 config_h.set_quoted('LIBINPUT_QUIRKS_SRCDIR', dir_src_quirks)
+if get_option('quirks-enable')
 install_subdir('quirks',
               exclude_files: ['README.md'],
               install_dir : dir_data,
@@ -980,6 +980,7 @@ endif
 ############ man pages ############
 if get_option('tools-enable')
 
+if 1 == 0
 man_config = configuration_data()
 man_config.set('LIBINPUT_VERSION', meson.project_version())
 man_config.set('LIBINPUT_DATA_DIR', dir_data)
@@ -1027,6 +1028,7 @@ configure_file(input : 'tools/libinput-quirks.man',
               configuration : man_config,
               install_dir : dir_man1,
               )
+endif
 
 endif
 ############ output files ############
index 65e6062..6d3783a 100644 (file)
@@ -1,4 +1,5 @@
 %define udev_dir %{_prefix}/lib/udev
+%define LIBINPUT_TOOLS_ENABLE false
 
 Name:           libinput
 Version:        1.17.0
@@ -67,7 +68,7 @@ meson setup \
     -Dtests=false \
     -Dudev-dir=%{udev_dir} \
     -Dzshcompletiondir=no \
-    -Dtools-enable=false \
+    -Dtools-enable=%{LIBINPUT_TOOLS_ENABLE} \
     -Dudev-enable=false \
     -Dquirks-enable=false \
     --prefix /usr \
@@ -96,8 +97,10 @@ ninja -C builddir install
 #%{udev_dir}/rules.d/*%{name}*
 
 ## disable tools ##
-#%{_bindir}/libinput
-#/usr/libexec/libinput/*
+%if "%{LIBINPUT_TOOLS_ENABLE}" == "true"
+%{_bindir}/libinput
+/usr/libexec/libinput/*
+%endif
 #%doc %{_mandir}/man?/*
 
 ## disable quirks data ##