--- /dev/null
+#include "test_hal_libinput_eventgen.h"
+
+int fd = 0;
+
+static inline void msleep(unsigned int ms)
+{
+ usleep(ms * 1000);
+}
+
+static int _write_event_to_device_node(int type, int code, int value)
+{
+ int nwrite;
+ struct input_event ev;
+
+ gettimeofday(&ev.time, NULL);
+
+ ev.type = type;
+ ev.code = code;
+ ev.value = value;
+
+ LOG("(type)%01d (code)%04x (value)%d\n",
+ ev.type, ev.code, ev.value);
+ nwrite = write(fd, &ev, sizeof(ev));
+
+ return nwrite;
+}
+
+static void _sync_gen(void)
+{
+ _write_event_to_device_node(EV_SYN, 0, 0);
+}
+
+static int _covert_button(int button)
+{
+ switch(button) {
+ case 0:
+ return BTN_LEFT;
+ case 1:
+ return BTN_RIGHT;
+ case 2:
+ return BTN_MIDDLE;
+ default:
+ return button;
+ }
+}
+
+static void _pointer_gen_button(int button, int value)
+{
+ _write_event_to_device_node(EV_KEY, button, value);
+}
+
+static void _pointer_gen_wheel(int value)
+{
+ _write_event_to_device_node(EV_REL, REL_WHEEL, value);
+ _sync_gen();
+}
+
+static void _pointer_gen_hwheel(int value)
+{
+ _write_event_to_device_node(EV_REL, REL_HWHEEL, value);
+ _sync_gen();
+}
+
+static void _pointer_gen_x(int value)
+{
+ _write_event_to_device_node(EV_REL, REL_X, value);
+}
+
+static void _pointer_gen_y(int value)
+{
+ _write_event_to_device_node(EV_REL, REL_Y, value);
+}
+
+static void _button_gen_down(int button)
+{
+ if(button <3)
+ button = _covert_button(button);
+
+ _pointer_gen_button(button,1);
+ _sync_gen();
+}
+
+static void _button_gen_up(int button)
+{
+ if(button <3)
+ button = _covert_button(button);
+
+ _pointer_gen_button(button, 0);
+ _sync_gen();
+}
+
+static void _pointer_gen_move(int x, int y)
+{
+ if(x != 0) _pointer_gen_x(x);
+ if(y != 0) _pointer_gen_y(y);
+ _sync_gen();
+}
+
+static void _input_mousegen(int button, int x, int y, int mouse_state)
+{
+ switch(mouse_state) {
+ case EVENT_STATE_PRESS:
+ _button_gen_down(button);
+ break;
+ case EVENT_STATE_RELEASE:
+ _button_gen_up(button);
+ msleep(30);
+ break;
+ case EVENT_STATE_MOTION:
+ if (button == BUTTON_WHEEL)
+ {
+ _pointer_gen_wheel(x);
+ }
+ else if (button == BUTTON_HWHEEL)
+ {
+ _pointer_gen_hwheel(y);
+ }
+ else
+ _pointer_gen_move(x, y);
+ break;
+ case EVENT_STATE_ALL:
+ _button_gen_down(button);
+ _button_gen_up(button);
+ break;
+ default:
+ return;
+ }
+}
+
+int input_mouse_event_gen(int _fd, int button, int x, int y, int state)
+{
+ if (_fd < 0) return -1;
+ fd = _fd;
+ _input_mousegen(button, x, y, state);
+
+ return 0;
+}
#include "test_hal_libinput_info.h"
+#include "test_hal_libinput_eventgen.h"
#include <limits.h>
#include <libevdev/libevdev.h>
#include <libevdev/libevdev-uinput.h>
+static const uint32_t screen_width = 100;
+static const uint32_t screen_height = 100;
+
struct record_device devices[10];
int devices_cnt = 0;
+struct record_event queue_record_event[1000];
+int queue_idx = 0;
+int pop_idx = -1;
+
#define NLONGS(n) (((n) + LONG_BIT - 1) / LONG_BIT)
static bool evdev_bit_is_set(const unsigned long *array, int bit)
const char *devnode;
switch(libinput_event_get_type(ev)) {
- case LIBINPUT_EVENT_DEVICE_ADDED:
- type = LIBINPUT_EVENT_DEVICE_ADDED;
- break;
- case LIBINPUT_EVENT_DEVICE_REMOVED:
- type = LIBINPUT_EVENT_DEVICE_REMOVED;
- break;
- default:
- abort();
+ case LIBINPUT_EVENT_DEVICE_ADDED:
+ type = LIBINPUT_EVENT_DEVICE_ADDED;
+ break;
+ case LIBINPUT_EVENT_DEVICE_REMOVED:
+ type = LIBINPUT_EVENT_DEVICE_REMOVED;
+ break;
+ default:
+ abort();
}
if(strstr(udev_device_get_property_value(udev_device, "DEVPATH"), "virtual")){
struct libinput_event *ev;
libinput_dispatch(li);
while((ev = libinput_get_event(li))) {
- switch (libinput_event_get_type(ev))
- {
- case LIBINPUT_EVENT_NONE:
- abort();
- case LIBINPUT_EVENT_DEVICE_ADDED:
- case LIBINPUT_EVENT_DEVICE_REMOVED:
- handle_device_notify(ev);
- break;
- default:
- break;
+ switch(libinput_event_get_type(ev)) {
+ case LIBINPUT_EVENT_NONE:
+ abort();
+ case LIBINPUT_EVENT_DEVICE_ADDED:
+ case LIBINPUT_EVENT_DEVICE_REMOVED:
+ handle_device_notify(ev);
+ break;
+ default:
+ break;
+ }
+ libinput_event_destroy(ev);
+ libinput_dispatch(li);
+ }
+ return 0;
+}
+
+static int
+handle_motion_event(struct libinput_event *ev)
+{
+ struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
+ double x = libinput_event_pointer_get_dx(p);
+ double y = libinput_event_pointer_get_dy(p);
+ double ux = libinput_event_pointer_get_dx_unaccelerated(p);
+ double uy = libinput_event_pointer_get_dy_unaccelerated(p);
+ enum libinput_event_type type;
+
+ switch(libinput_event_get_type(ev)) {
+ case LIBINPUT_EVENT_POINTER_MOTION:
+ type = LIBINPUT_EVENT_POINTER_MOTION;
+ break;
+ default:
+ abort();
+ }
+ LOG("delta: %6.2f/%6.2f , unaccel: (%+6.2f/%+6.2f)\n", x, y, ux, uy);
+ LOG("type = %d, button = %d, x = %d, y = %d, state = %d\n", queue_record_event[pop_idx].p.event_type, queue_record_event[pop_idx].p.button,
+ queue_record_event[pop_idx].p.x, queue_record_event[pop_idx].p.y, queue_record_event[pop_idx].p.state);
+
+ 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;
+
+ 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);
+
+ return 0;
+}
+
+static int
+handle_absmotion_event(struct libinput_event *ev)
+{
+ struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
+ double x = libinput_event_pointer_get_absolute_x(p);
+ double y = libinput_event_pointer_get_absolute_y(p);
+ double tx = libinput_event_pointer_get_absolute_x_transformed(p, screen_width);
+ double ty = libinput_event_pointer_get_absolute_y_transformed(p, screen_height);
+ enum libinput_event_type type;
+
+ switch(libinput_event_get_type(ev)) {
+ case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
+ type = LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE;
+ break;
+ default:
+ abort();
+ }
+ LOG("point: %6.2f/%6.2f, transformed: %6.2f/%6.2f\n", x, y, tx, ty);
+ LOG("type = %d, button = %d, x = %d, y = %d, state = %d\n", queue_record_event[pop_idx].p.event_type, queue_record_event[pop_idx].p.button,
+ queue_record_event[pop_idx].p.x, queue_record_event[pop_idx].p.y, queue_record_event[pop_idx].p.state);
+ EXPECT_EQ(queue_record_event[pop_idx].p.event_type, type);
+ return 0;
+}
+
+static int
+handle_pointer_button_event(struct libinput_event *ev)
+{
+ struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
+ enum libinput_event_type type;
+ enum libinput_button_state state;
+ const char *buttonname;
+ int button;
+
+ switch(libinput_event_get_type(ev)) {
+ case LIBINPUT_EVENT_POINTER_BUTTON:
+ type = LIBINPUT_EVENT_POINTER_BUTTON;
+ break;
+ default:
+ abort();
+ }
+
+ button = libinput_event_pointer_get_button(p);
+ buttonname = libevdev_event_code_get_name(EV_KEY, button);
+ state = libinput_event_pointer_get_button_state(p);
+
+ LOG("%s (%d) %s, seat count: %u\n",
+ buttonname ? buttonname : "???",
+ button,
+ state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released",
+ libinput_event_pointer_get_seat_button_count(p));
+
+ if(queue_record_event[pop_idx].p.event_type != type) return -1;
+ if(queue_record_event[pop_idx].p.button != button) return -1;
+ if(queue_record_event[pop_idx].p.state != state) return -1;
+
+ LOG("type = %d, button = %d, x = %d, y = %d, state = %d\n", queue_record_event[pop_idx].p.event_type, queue_record_event[pop_idx].p.button,
+ queue_record_event[pop_idx].p.x, queue_record_event[pop_idx].p.y, queue_record_event[pop_idx].p.state);
+
+ EXPECT_EQ(queue_record_event[pop_idx].p.event_type, type);
+ EXPECT_EQ(queue_record_event[pop_idx].p.button, button);
+ EXPECT_EQ(queue_record_event[pop_idx].p.state, state);
+ return 0;
+}
+
+static int
+handle_key_event(struct libinput_event *ev)
+{
+ return 0;
+}
+
+static int
+handle_pointer_axis_event(struct libinput_event *ev)
+{
+ struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
+ enum libinput_event_type type;
+ const char *source;
+ double h = 0, v = 0;
+ int hd = 0, vd = 0;
+
+ switch(libinput_event_get_type(ev)) {
+ case LIBINPUT_EVENT_POINTER_AXIS:
+ type = LIBINPUT_EVENT_POINTER_AXIS;
+ break;
+ default:
+ abort();
+ }
+
+ if (libinput_event_pointer_has_axis(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
+ h = libinput_event_pointer_get_axis_value(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ hd = libinput_event_pointer_get_axis_value_discrete(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ }
+ if (libinput_event_pointer_has_axis(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
+ v = libinput_event_pointer_get_axis_value(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ vd = libinput_event_pointer_get_axis_value_discrete(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ }
+ switch(libinput_event_pointer_get_axis_source(p)) {
+ case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: source = "wheel"; break;
+ case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: source = "finger"; break;
+ case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: source = "continuous"; break;
+ case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT: source = "wheel-tilt"; break;
+ default:
+ source = "unknown";
+ break;
+ }
+
+ LOG("axes: %2.2f, %2.2f, discrete: %d, %d, source: %s\n", h, v, hd, vd, source);
+ EXPECT_EQ(queue_record_event[pop_idx].p.event_type, type);
+ return 0;
+}
+
+static int
+handle_touch_event(struct libinput_event *ev)
+{
+ return 0;
+}
+
+int handle_libinput_event(struct libinput *li)
+{
+ int rc = -1;
+ struct libinput_event *ev;
+
+ libinput_dispatch(li);
+ while((ev = libinput_get_event(li))) {
+ switch(libinput_event_get_type(ev)) {
+ case LIBINPUT_EVENT_NONE:
+ abort();
+ case LIBINPUT_EVENT_DEVICE_ADDED:
+ case LIBINPUT_EVENT_DEVICE_REMOVED:
+ rc = handle_device_notify(ev);
+ break;
+ case LIBINPUT_EVENT_KEYBOARD_KEY:
+ pop_idx++;
+ rc = handle_key_event(ev);
+ break;
+ case LIBINPUT_EVENT_POINTER_MOTION:
+ pop_idx++;
+ rc = handle_motion_event(ev);
+ break;
+ case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
+ pop_idx++;
+ rc = handle_absmotion_event(ev);
+ break;
+ case LIBINPUT_EVENT_POINTER_BUTTON:
+ pop_idx++;
+ rc = handle_pointer_button_event(ev);
+ break;
+ case LIBINPUT_EVENT_POINTER_AXIS:
+ pop_idx++;
+ rc = handle_pointer_axis_event(ev);
+ break;
+ case LIBINPUT_EVENT_TOUCH_DOWN:
+ case LIBINPUT_EVENT_TOUCH_UP:
+ case LIBINPUT_EVENT_TOUCH_MOTION:
+ case LIBINPUT_EVENT_TOUCH_CANCEL:
+ pop_idx++;
+ rc = handle_touch_event(ev);
+ break;
+ case LIBINPUT_EVENT_TOUCH_FRAME:
+ rc = handle_touch_event(ev);
+ break;
+ default:
+ break;
}
libinput_event_destroy(ev);
libinput_dispatch(li);
+ if(rc < 0) return -1;
}
return 0;
}
+
+int create_mouse_event(struct libinput *li, int idx)
+{
+ int fd = -1;
+ int n = 0;
+
+ struct record_event rc_e;
+ 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_BUTTON, (int) BTN_LEFT, 200, 200, 0}
+ };
+
+ if(devices[idx].cap == LIBINPUT_DEVICE_CAP_POINTER){
+ LOG("create_mouse_event\n");
+ fd = open(devices[idx].path, O_RDWR);
+ if (fd < 0) {
+ LOGE("ERROR: could not open device\n");
+ return -1;
+ }
+
+ n = sizeof(p)/sizeof(struct record_libinput_event_pointer);
+ rc_e.device = LIBINPUT_DEVICE_CAP_POINTER;
+ for(int i=0; i<n; ++i)
+ {
+ rc_e.p = p[i];
+
+ if(input_mouse_event_gen(fd, p[i].button, p[i].x, p[i].y, p[i].state) < 0) {
+ LOG("No device\n");
+ continue;
+ }
+ queue_record_event[queue_idx++] = rc_e;
+ }
+
+ libinput_dispatch(li);
+ close(fd);
+ }
+ else
+ return -1;
+ return 0;
+}
+
+bool validate_mouse_event(struct libinput *li)
+{
+ bool val = false;
+ bool checked = false;
+ int ret = 0;
+
+ for(int i=0; i< devices_cnt; ++i) {
+ if(devices[i].cap == LIBINPUT_DEVICE_CAP_POINTER) {
+ checked = true;
+ LOG("LIBINPUT_DEVICE_CAP_POINTER, path = %s\n", devices[i].path);
+ queue_idx = 0;
+ pop_idx = -1;
+ create_mouse_event(li, i);
+ ret = handle_libinput_event(li);
+ if(queue_idx == (pop_idx+1) && !ret) {
+ val = true;
+ }
+ }
+ if(val) return true;
+ }
+ if(!val && !checked){
+ LOG("No Devices\n");
+ return true;
+ }
+ return val;
+}