From: jeon Date: Fri, 17 Apr 2020 09:17:38 +0000 (+0900) Subject: e_info: add a touch generation utility X-Git-Tag: submit/tizen/20200422.061536~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a4d289e8386de5d201cd3b7cb499900af18782b3;p=platform%2Fupstream%2Fenlightenment.git e_info: add a touch generation utility Change-Id: I1095be1687cf8141d00ff6c2e589b1eb81623969 --- diff --git a/src/bin/e_info_client.c b/src/bin/e_info_client.c index 62c295aac2..8ce6e134ea 100644 --- a/src/bin/e_info_client.c +++ b/src/bin/e_info_client.c @@ -5553,6 +5553,16 @@ _e_info_client_inputgen_usage(void) printf(" example> enlightenment_info -keygen --name=XF86Back\n"); printf(" enlightenment_info -keygen --code=166 --state=down\n"); printf(" enlightenment_info -keygen --name=XF86Back --state=0\n"); + printf("\n\n"); + printf(" enlightenment_info -touchgen\n"); + printf(" \t--idx: touch index want to generate (default: 0)\n"); + printf(" \t--axis: touch axis want to generate\n"); + printf(" \t--state: touch event state want to generate [press/down/1] [release/up/0] [motion/move/2] (default: Press/Motion/Release pair)\n"); + printf("\n"); + printf(" you need to input axis information to generate touch events\n"); + printf(" example> enlightenment_info -touchgen --axis=100,200\n"); + printf(" enlightenment_info -touchgen --idx=1 --axis=200,300\n"); + printf(" enlightenment_info -touchgen --idx=0 --axis=300,100 --state=down\n"); printf("\n"); } @@ -5702,7 +5712,7 @@ void _e_info_client_proc_keygen(int argc, char **argv) { char name[16] = {0, }; - int state = E_INFO_KEY_STATE_ALL, code = 0, i; + int state = E_INFO_EVENT_STATE_ALL, code = 0, i; char *tmp = NULL; if (argc < 3) @@ -5730,13 +5740,13 @@ _e_info_client_proc_keygen(int argc, char **argv) !strncmp(tmp, "down", sizeof("down")) || !strncmp(tmp, "1", sizeof("1"))) { - state = E_INFO_KEY_STATE_PRESS; + state = E_INFO_EVENT_STATE_PRESS; } else if (!strncmp(tmp, "release", sizeof("release")) || !strncmp(tmp, "up", sizeof("up")) || !strncmp(tmp, "0", sizeof("0"))) { - state = E_INFO_KEY_STATE_RELEASE; + state = E_INFO_EVENT_STATE_RELEASE; } else { @@ -5766,6 +5776,115 @@ _e_info_client_proc_keygen(int argc, char **argv) return; } +static void +_e_info_client_cb_touchgen(const Eldbus_Message *msg) +{ + const char *errname = NULL, *errtext = NULL; + char *result = NULL; + + EINA_SAFETY_ON_TRUE_GOTO(eldbus_message_error_get(msg, &errname, &errtext), err); + + EINA_SAFETY_ON_FALSE_GOTO(eldbus_message_arguments_get(msg, "s", &result), err); + + if (strncmp(result, E_INFO_INPUT_RESULT_NONE, sizeof(E_INFO_INPUT_RESULT_NONE))) + printf("Touchgen Failed: %s\n", result); + + return; + +err: + if(errname || errtext) + printf("errname : %s, errmsg : %s\n", errname, errtext); + else + printf("Error occurred in _e_info_client_cb_touchgen\n"); +} + +void +_e_info_client_proc_touchgen(int argc, char **argv) +{ + char name[16] = {0, }; + int state = E_INFO_EVENT_STATE_ALL, idx = 0, x = -1, y = -1, cnt = 0, i; + char *tmp = NULL, *buf = NULL, *buf_ptr = NULL; + + if (argc < 3) + { + _e_info_client_inputgen_usage(); + return; + } + + for (i = 2; i < argc; i++) + { + if (!strncmp(argv[i], "--idx=", sizeof("--idx=") - 1)) + { + tmp = argv[i] + sizeof("--idx=") - 1; + idx = atoi(tmp); + } + else if (!strncmp(argv[i], "--axis=", sizeof("--axis=") - 1)) + { + tmp = argv[i] + sizeof("--axis=") - 1; + buf = strtok_r(tmp, ",", &buf_ptr); + if (!buf) + { + printf("Please insert correct axis. --axis=100,200\n"); + return; + } + while (buf) + { + if (cnt == 0) x = atoi(buf); + else if (cnt == 1) y = atoi(buf); + else + { + printf("Please insert valid axis. --axis=100,200\n"); + return; + } + buf = strtok_r(NULL, ",", &buf_ptr); + cnt++; + } + } + else if (!strncmp(argv[i], "--state=", sizeof("--state=") - 1)) + { + tmp = argv[i] + sizeof("--state=") - 1; + if (!strncmp(tmp, "press", sizeof("press")) || + !strncmp(tmp, "down", sizeof("down")) || + !strncmp(tmp, "1", sizeof("1"))) + { + state = E_INFO_EVENT_STATE_PRESS; + } + else if (!strncmp(tmp, "release", sizeof("release")) || + !strncmp(tmp, "up", sizeof("up")) || + !strncmp(tmp, "0", sizeof("0"))) + { + state = E_INFO_EVENT_STATE_RELEASE; + } + else if (!strncmp(tmp, "motion", sizeof("motion")) || + !strncmp(tmp, "move", sizeof("move")) || + !strncmp(tmp, "2", sizeof("2"))) + { + state = E_INFO_EVENT_STATE_MOTION; + } + else + { + printf("Please input correct key state (press/down/1) or (release/up/0)\n"); + return; + } + } + else + { + _e_info_client_inputgen_usage(); + return; + } + } + + if ((x < 0) || (y < 0)) + { + printf("Please insert correct axis values (greater than 0)\n"); + return; + } + + if (!_e_info_client_eldbus_message_with_args("touchgen", _e_info_client_cb_touchgen, "iiii", idx, x, y, state)) + return; +} + + static void _e_info_client_cb_filter(const Eldbus_Message *msg) { @@ -6223,6 +6342,12 @@ ProcInfo procs_to_input[] = "Generate key events", /* Description */ _e_info_client_proc_keygen /* func */ }, + { + "touchgen", /* Option */ + NULL,/* Params */ + "Generate touch events", /* Description */ + _e_info_client_proc_touchgen /* func */ + }, }; static Eina_List *list_tracelogs = NULL; diff --git a/src/bin/e_info_server.c b/src/bin/e_info_server.c index bbe1d0ce48..beb65320cb 100644 --- a/src/bin/e_info_server.c +++ b/src/bin/e_info_server.c @@ -6650,6 +6650,27 @@ _e_info_server_cb_keygen(const Eldbus_Service_Interface *iface EINA_UNUSED, cons return reply; } +static Eldbus_Message * +_e_info_server_cb_touchgen(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message *reply; + char *result = NULL; + int idx = 0, x = -1, y = -1, state = 0; + + if (!eldbus_message_arguments_get(msg, "iiii", &idx, &x, &y, &state)) + { + return eldbus_message_error_new(msg, "TouchgenFailed", + "toutgen: an attempt to generate touch event from method call message failed"); + } + + result = e_info_server_input_touchgen(idx, x, y, state); + reply = eldbus_message_method_return_new(msg); + + eldbus_message_arguments_append(reply, "s", result); + + return reply; +} + static Eldbus_Message * _e_info_server_cb_filter(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) { @@ -6868,6 +6889,7 @@ static const Eldbus_Method methods[] = { { "init_device", ELDBUS_ARGS({"us", "device information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_init_device, 0}, { "deinit_device", NULL, NULL, _e_info_server_cb_deinit_device, 0}, { "keygen", ELDBUS_ARGS({"sii", "key information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_keygen, 0}, + { "touchgen", ELDBUS_ARGS({"iiii", "touch information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_touchgen, 0}, { "filter", ELDBUS_ARGS({"sis", "win_id, on(1)/off(0), filter name"}), ELDBUS_ARGS({"s", "result of request"}), _e_info_server_cb_filter, 0}, { NULL, NULL, NULL, NULL, 0 } }; diff --git a/src/bin/e_info_server_input.c b/src/bin/e_info_server_input.c index 08f73bba5b..cd7cd677cd 100644 --- a/src/bin/e_info_server_input.c +++ b/src/bin/e_info_server_input.c @@ -23,7 +23,7 @@ static E_Info_Server_Input _e_info_input = static int -_e_info_input_keygen_create_device(const char *dev_name) +_e_info_input_create_keyboard_device(const char *dev_name) { int fd_uinput = -1, nwrite = 0, i; struct uinput_user_dev dev_uinput = {0, }; @@ -59,7 +59,82 @@ _e_info_input_keygen_create_device(const char *dev_name) } static int -_e_info_input_keygen_open_device(char *identifier) +_e_info_input_create_touch_device(const char *dev_name) +{ + int fd_uinput = -1, nwrite = 0; + struct uinput_user_dev dev_uinput = {0, }; + E_Output *output; + int w = 0, h = 0; + + fd_uinput = open("/dev/uinput", O_WRONLY | O_NDELAY); + EINA_SAFETY_ON_FALSE_RETURN_VAL(fd_uinput >= 0, -1); + + output = e_comp_screen_primary_output_get(e_comp->e_comp_screen); + e_output_size_get(output, &w, &h); + + if (w <= 0) w = 4096; + if (h <= 0) h = 4096; + + WRN("Failed to get output size for creating touch device in e_info. So set arbitrary output size [%d x %d]\n", w, h); + + strncpy(dev_uinput.name, dev_name, UINPUT_MAX_NAME_SIZE - 1); + dev_uinput.id.version = 4; + dev_uinput.id.bustype = BUS_VIRTUAL; + + ioctl(fd_uinput, UI_SET_EVBIT, EV_KEY); + ioctl(fd_uinput, UI_SET_EVBIT, EV_SYN); + ioctl(fd_uinput, UI_SET_EVBIT, EV_MSC); + ioctl(fd_uinput, UI_SET_EVBIT, EV_ABS); + + ioctl(fd_uinput, UI_SET_KEYBIT, BTN_TOUCH); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_X); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_Y); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_MT_SLOT); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_MT_TOUCH_MINOR); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_MT_WIDTH_MAJOR); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_MT_POSITION_X); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_MT_POSITION_Y); + ioctl(fd_uinput, UI_SET_ABSBIT, ABS_MT_TRACKING_ID); + ioctl(fd_uinput, UI_SET_MSCBIT, MSC_SCAN); + + dev_uinput.absmin[ABS_X] = 0; + dev_uinput.absmax[ABS_X] = w - 1; + dev_uinput.absmin[ABS_Y] = 0; + dev_uinput.absmax[ABS_Y] = h - 1; + dev_uinput.absmin[ABS_MT_SLOT] = 0; + dev_uinput.absmax[ABS_MT_SLOT] = 9; + dev_uinput.absmin[ABS_MT_TOUCH_MAJOR] = 0; + dev_uinput.absmax[ABS_MT_TOUCH_MAJOR] = 255; + dev_uinput.absmin[ABS_MT_TOUCH_MINOR] = 0; + dev_uinput.absmax[ABS_MT_TOUCH_MINOR] = 255; + dev_uinput.absmin[ABS_MT_WIDTH_MAJOR] = 0; + dev_uinput.absmax[ABS_MT_WIDTH_MAJOR] = 255; + dev_uinput.absmin[ABS_MT_POSITION_X] = 0; + dev_uinput.absmax[ABS_MT_POSITION_X] = w - 1; + dev_uinput.absmin[ABS_MT_POSITION_Y] = 0; + dev_uinput.absmax[ABS_MT_POSITION_Y] = h - 1; + dev_uinput.absmin[ABS_MT_TRACKING_ID] = 0; + dev_uinput.absmax[ABS_MT_TRACKING_ID] = 65535; + dev_uinput.absmin[ABS_MT_ORIENTATION] = 0; + dev_uinput.absmax[ABS_MT_ORIENTATION] = 2; + + /* Create input device into input sub-system */ + nwrite = write(fd_uinput, &dev_uinput, sizeof(dev_uinput)); + if (nwrite < 0) WRN("Failed to write for create device using uinput\n"); + + if (ioctl(fd_uinput, UI_DEV_CREATE)) + { + WRN("Failed to create device(%s).", dev_name); + close (fd_uinput); + return -1; + } + + return fd_uinput; +} + +static int +_e_info_input_open_device(char *identifier) { int fd = -1; @@ -115,18 +190,90 @@ _key_gen_up(int key_code) _sync_gen(); } +static void +_touch_gen_mt_slot(int value) +{ + _write_event_to_device_node(EV_ABS, ABS_MT_SLOT, value); +} + +static void +_touch_gen_mt_tracking_id(int value) +{ + _write_event_to_device_node(EV_ABS, ABS_MT_TRACKING_ID, value); +} + +static void +_touch_gen_mt_touch_major(int value) +{ + _write_event_to_device_node(EV_ABS, ABS_MT_TOUCH_MAJOR, value); +} + +static void +_touch_gen_mt_touch_minor(int value) +{ + _write_event_to_device_node(EV_ABS, ABS_MT_TOUCH_MINOR, value); +} + +static void +_touch_gen_mt_position_x(int value) +{ + _write_event_to_device_node(EV_ABS, ABS_MT_POSITION_X, value); +} + +static void +_touch_gen_mt_position_y(int value) +{ + _write_event_to_device_node(EV_ABS, ABS_MT_POSITION_Y, value); +} + +static void +_touch_gen_down(int idx, int x, int y) +{ +#define MAX_TRACKING_ID 65535 + static int tracking_id = 0; + + _touch_gen_mt_slot(idx); + _touch_gen_mt_tracking_id(tracking_id); + tracking_id++; + if (tracking_id > MAX_TRACKING_ID) + tracking_id = 0; + + _touch_gen_mt_touch_major(10); + _touch_gen_mt_touch_minor(5); + _touch_gen_mt_position_x(x); + _touch_gen_mt_position_y(y); + _sync_gen(); +} + +static void +_touch_gen_move(int idx, int x, int y) +{ + _touch_gen_mt_slot(idx); + _touch_gen_mt_position_x(x); + _touch_gen_mt_position_y(y); + _sync_gen(); +} + +static void +_touch_gen_up(int idx) +{ + _touch_gen_mt_slot(idx); + _touch_gen_mt_tracking_id(-1); + _sync_gen(); +} + static void _e_info_input_keygen(int key_code, int key_state) { switch (key_state) { - case E_INFO_KEY_STATE_PRESS: + case E_INFO_EVENT_STATE_PRESS: _key_gen_down(key_code); break; - case E_INFO_KEY_STATE_RELEASE: + case E_INFO_EVENT_STATE_RELEASE: _key_gen_up(key_code); break; - case E_INFO_KEY_STATE_ALL: + case E_INFO_EVENT_STATE_ALL: _key_gen_down(key_code); _key_gen_up(key_code); break; @@ -136,7 +283,32 @@ _e_info_input_keygen(int key_code, int key_state) } static void -_e_info_input_keygen_close_device(void) +_e_info_input_touchgen(int idx, int x, int y, int touch_state) +{ + switch (touch_state) + { + case E_INFO_EVENT_STATE_PRESS: + _touch_gen_down(idx, x, y); + break; + case E_INFO_EVENT_STATE_RELEASE: + _touch_gen_up(idx); + break; + case E_INFO_EVENT_STATE_MOTION: + _touch_gen_move(idx, x, y); + break; + case E_INFO_EVENT_STATE_ALL: + _touch_gen_down(idx, x, y); + _touch_gen_move(idx, x, y); + _touch_gen_up(idx); + break; + default: + return; + } +} + + +static void +_e_info_input_close_device(void) { int ret; @@ -163,13 +335,15 @@ e_info_server_input_init_device(unsigned int type, char *name) { if (type & E_INPUT_SEAT_KEYBOARD) { - fd = _e_info_input_keygen_create_device(name); + fd = _e_info_input_create_keyboard_device(name); _e_info_input.gen.virtual_dev = EINA_TRUE; _e_info_input.gen.fd = fd; } - else + if (type & E_INPUT_SEAT_TOUCH) { - WRN("Currently only keyboard is supported.\n"); + fd = _e_info_input_create_touch_device(name); + _e_info_input.gen.virtual_dev = EINA_TRUE; + _e_info_input.gen.fd = fd; } } else @@ -179,11 +353,9 @@ e_info_server_input_init_device(unsigned int type, char *name) EINA_LIST_FOREACH(device_list, l, dev) { - if (ecore_device_class_get(dev) != ECORE_DEVICE_CLASS_KEYBOARD) - continue; if (!e_util_strcmp(name, ecore_device_identifier_get(dev))) { - fd = _e_info_input_keygen_open_device(name); + fd = _e_info_input_open_device(name); _e_info_input.gen.virtual_dev = EINA_FALSE; _e_info_input.gen.fd = fd; } @@ -206,7 +378,7 @@ e_info_server_input_deinit_device(void) if (_e_info_input.gen.fd < 0) return; if (_e_info_input.gen.virtual_dev) - _e_info_input_keygen_close_device(); + _e_info_input_close_device(); else { close(_e_info_input.gen.fd); @@ -218,8 +390,8 @@ e_info_server_input_deinit_device(void) return; } -char -*e_info_server_input_keygen(char *name, int code, int state) +char * +e_info_server_input_keygen(char *name, int code, int state) { if (_e_info_input.gen.fd < 0) return "Initialize device first"; @@ -234,3 +406,14 @@ char return E_INFO_INPUT_RESULT_NONE; } + +char * +e_info_server_input_touchgen(int idx, int x, int y, int state) +{ + if (_e_info_input.gen.fd < 0) return "Initialize device first"; + + _e_info_input_touchgen(idx, x, y, state); + + return E_INFO_INPUT_RESULT_NONE; +} + diff --git a/src/bin/e_info_server_input.h b/src/bin/e_info_server_input.h index 0a0484bd9d..3cc8ea140a 100644 --- a/src/bin/e_info_server_input.h +++ b/src/bin/e_info_server_input.h @@ -6,5 +6,6 @@ char *e_info_server_input_init_device(unsigned int type, char *name); void e_info_server_input_deinit_device(void); char *e_info_server_input_keygen(char *name, int code, int state); +char *e_info_server_input_touchgen(int idx, int x, int y, int state); #endif diff --git a/src/bin/e_info_shared_types.h b/src/bin/e_info_shared_types.h index bd662f077a..0349a5bb82 100644 --- a/src/bin/e_info_shared_types.h +++ b/src/bin/e_info_shared_types.h @@ -285,12 +285,17 @@ typedef enum "Example:\n" \ "\twinfo -screen_info\n" +/* -------------------------------------------------------------------------- */ +/* INPUT GENERATION */ +/* -------------------------------------------------------------------------- */ + typedef enum { - E_INFO_KEY_STATE_RELEASE = 0, - E_INFO_KEY_STATE_PRESS, - E_INFO_KEY_STATE_ALL -} E_Info_Key_State; + E_INFO_EVENT_STATE_RELEASE = 0, + E_INFO_EVENT_STATE_PRESS, + E_INFO_EVENT_STATE_MOTION, + E_INFO_EVENT_STATE_ALL +} E_Info_Event_State; #define E_INFO_INPUT_RESULT_NONE "None"