From: jeon Date: Mon, 27 Apr 2020 09:08:51 +0000 (+0900) Subject: e_info: add mouse event generation utility X-Git-Tag: submit/tizen/20200427.230449~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=135c477082089f62d10e1813456c6f6eb4f46f82;p=platform%2Fupstream%2Fenlightenment.git e_info: add mouse event generation utility Change-Id: I0d13ed848ffd5ef80e63fe03ccaf7cbd0d93be61 --- diff --git a/src/bin/e_info_client.c b/src/bin/e_info_client.c index e9bf97de91..5fb088570c 100644 --- a/src/bin/e_info_client.c +++ b/src/bin/e_info_client.c @@ -5563,6 +5563,25 @@ _e_info_client_inputgen_usage(void) 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\n"); + printf(" enlightenment_info -mousegen\n"); + printf(" \t--button: button number want to generate (default: left button(0/272))\n"); + printf(" \t\t button number following linux input.h so BTN_LEFT value is 272\n"); + printf(" \t\t but to generate button simply support 3 button (0: left, 1: right, 2: middle)\n"); + printf(" \t\t you can use --btn instead\n"); + printf(" \t--axis: mouse relative axis want to generate\n"); + printf(" \t--state: mouse event state want to generate [press/down/1] [release/up/0] [motion/move/2] (default: Motion or Press/Release pair)\n"); + printf(" \t\t if you add option --axis, default state is move, but if you add option --button, default state is down/up pair\n"); + printf(" \t--wheel: mouse wheel event want to generate\n"); + printf(" \t--hwheel: mouse horizental wheel event want to generate\n"); + printf("\n"); + printf(" you need to choice either axis or button to generate mouse events\n"); + printf(" example> enlightenment_info -mousegen --axis=5,-10 --state=move\n"); + printf(" enlightenment_info -mousegen --axis=-12,20\n"); + printf(" enlightenment_info -mousegen --button=0 --state=down\n"); + printf(" enlightenment_info -mousegen --btn=1\n"); + printf(" enlightenment_info -mousegen --wheel=1\n"); + printf(" enlightenment_info -mousegen --hwheel=-1\n"); printf("\n"); } @@ -5622,7 +5641,8 @@ _e_info_client_proc_init_device(int argc, char **argv) } while (buf) { - if (!strncmp(buf, "mouse", sizeof("mouse"))) + if (!strncmp(buf, "mouse", sizeof("mouse")) || + !strncmp(buf, "pointer", sizeof("pointer"))) { type |= E_INPUT_SEAT_POINTER; } @@ -5883,6 +5903,134 @@ _e_info_client_proc_touchgen(int argc, char **argv) return; } +static void +_e_info_client_cb_mousegen(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("Mousegen 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_mousegen\n"); +} + +void +_e_info_client_proc_mousegen(int argc, char **argv) +{ + int state = E_INFO_EVENT_STATE_ALL, button = 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], "--button=", sizeof("--button=") - 1)) + { + tmp = argv[i] + sizeof("--button=") - 1; + button = atoi(tmp); + } + else if (!strncmp(argv[i], "--btn=", sizeof("--btn=") - 1)) + { + tmp = argv[i] + sizeof("--btn=") - 1; + button = 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=5,10\n"); + return; + } + while (buf) + { + if (cnt == 0) x = atoi(buf); + else if (cnt == 1) y = atoi(buf); + else + { + printf("Please insert correct axis. --axis=5,10\n"); + return; + } + buf = strtok_r(NULL, ",", &buf_ptr); + cnt++; + } + state = E_INFO_EVENT_STATE_MOTION; + } + 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 mouse state (press/down/1), (release/up/0) or (motion/move/2)\n"); + return; + } + } + else if (!strncmp(argv[i], "--wheel=", sizeof("--wheel=") - 1)) + { + tmp = argv[i] + sizeof("--wheel=") - 1; + button = E_INFO_BUTTON_WHEEL; + state = E_INFO_EVENT_STATE_MOTION; + x = atoi(tmp); + } + else if (!strncmp(argv[i], "--hwheel=", sizeof("--hwheel=") - 1)) + { + tmp = argv[i] + sizeof("--hwheel=") - 1; + button = E_INFO_BUTTON_HWHEEL; + state = E_INFO_EVENT_STATE_MOTION; + y = atoi(tmp); + } + else + { + _e_info_client_inputgen_usage(); + return; + } + } + + if (state == E_INFO_EVENT_STATE_MOTION && ((x == 0) && (y == 0))) + { + printf("Please insert correct axis values for motion events\n"); + return; + } + + if (!_e_info_client_eldbus_message_with_args("mousegen", _e_info_client_cb_mousegen, "iiii", button, x, y, state)) + return; +} + + static void _e_info_client_cb_filter(const Eldbus_Message *msg) @@ -6347,6 +6495,12 @@ ProcInfo procs_to_input[] = "Generate touch events", /* Description */ _e_info_client_proc_touchgen /* func */ }, + { + "mousegen", /* Option */ + NULL,/* Params */ + "Generate mouse events", /* Description */ + _e_info_client_proc_mousegen /* func */ + }, }; static Eina_List *list_tracelogs = NULL; diff --git a/src/bin/e_info_server.c b/src/bin/e_info_server.c index 96052cfdd6..c986d233a7 100644 --- a/src/bin/e_info_server.c +++ b/src/bin/e_info_server.c @@ -6676,6 +6676,28 @@ _e_info_server_cb_touchgen(const Eldbus_Service_Interface *iface EINA_UNUSED, co return reply; } +static Eldbus_Message * +_e_info_server_cb_mousegen(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) +{ + Eldbus_Message *reply; + char *result = NULL; + int button = 0, x = -1, y = -1, state = 0; + + if (!eldbus_message_arguments_get(msg, "iiii", &button, &x, &y, &state)) + { + return eldbus_message_error_new(msg, "MousegenFailed", + "mousegen: an attempt to generate mouse event from method call message failed"); + } + + result = e_info_server_input_mousegen(button, 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) { @@ -6895,6 +6917,7 @@ static const Eldbus_Method methods[] = { { "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}, + { "mousegen", ELDBUS_ARGS({"iiii", "mouse information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_mousegen, 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 2eeb28668e..e55dae3298 100644 --- a/src/bin/e_info_server_input.c +++ b/src/bin/e_info_server_input.c @@ -133,6 +133,48 @@ _e_info_input_create_touch_device(const char *dev_name) return fd_uinput; } +static int +_e_info_input_create_pointer_device(const char *dev_name) +{ + int fd_uinput = -1, nwrite = 0, i; + struct uinput_user_dev dev_uinput = {0, }; + + fd_uinput = open("/dev/uinput", O_WRONLY | O_NDELAY); + EINA_SAFETY_ON_FALSE_RETURN_VAL(fd_uinput >= 0, -1); + + 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_REL); + ioctl(fd_uinput, UI_SET_EVBIT, EV_SYN); + ioctl(fd_uinput, UI_SET_EVBIT, EV_MSC); + + ioctl(fd_uinput, UI_SET_RELBIT, REL_X); + ioctl(fd_uinput, UI_SET_RELBIT, REL_Y); + ioctl(fd_uinput, UI_SET_RELBIT, REL_WHEEL); + ioctl(fd_uinput, UI_SET_RELBIT, REL_HWHEEL); + + for (i = BTN_MISC; i <= BTN_TASK; i++) + ioctl(fd_uinput, UI_SET_KEYBIT, i); + + ioctl(fd_uinput, UI_SET_MSCBIT, MSC_SCAN); + + /* 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 (err: %m)\n"); + + if (ioctl(fd_uinput, UI_DEV_CREATE)) + { + WRN("Failed to create %s device (err: %m)", dev_name); + close (fd_uinput); + return -1; + } + + return fd_uinput; +} + static int _e_info_input_open_device(char *identifier) { @@ -161,6 +203,7 @@ _write_event_to_device_node(int type, int code, int value) ev.value = value; nwrite = write(_e_info_input.gen.fd, &ev, sizeof(ev)); + return nwrite; } @@ -226,6 +269,54 @@ _touch_gen_mt_position_y(int value) _write_event_to_device_node(EV_ABS, ABS_MT_POSITION_Y, value); } +static int +_convert_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_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 +_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 _touch_gen_down(int idx, int x, int y) { @@ -262,6 +353,34 @@ _touch_gen_up(int idx) _sync_gen(); } +static void +_button_gen_down(int button) +{ + if (button < 3) + button = _convert_button(button); + + _pointer_gen_button(button, 1); + _sync_gen(); +} + +static void +_button_gen_up(int button) +{ + if (button < 3) + button = _convert_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 _e_info_input_keygen(int key_code, int key_state) { @@ -306,6 +425,37 @@ _e_info_input_touchgen(int idx, int x, int y, int touch_state) } } +static void +_e_info_input_mousegen(int button, int x, int y, int mouse_state) +{ + switch (mouse_state) + { + case E_INFO_EVENT_STATE_PRESS: + _button_gen_down(button); + break; + case E_INFO_EVENT_STATE_RELEASE: + _button_gen_up(button); + break; + case E_INFO_EVENT_STATE_MOTION: + if (button == E_INFO_BUTTON_WHEEL) + { + _pointer_gen_wheel(x); + } + else if (button == E_INFO_BUTTON_HWHEEL) + { + _pointer_gen_hwheel(y); + } + else + _pointer_gen_move(x, y); + break; + case E_INFO_EVENT_STATE_ALL: + _button_gen_down(button); + _button_gen_up(button); + break; + default: + return; + } +} static void _e_info_input_close_device(void) @@ -345,6 +495,12 @@ e_info_server_input_init_device(unsigned int type, char *name) _e_info_input.gen.virtual_dev = EINA_TRUE; _e_info_input.gen.fd = fd; } + if (type & E_INPUT_SEAT_POINTER) + { + fd = _e_info_input_create_pointer_device(name); + _e_info_input.gen.virtual_dev = EINA_TRUE; + _e_info_input.gen.fd = fd; + } } else { @@ -417,3 +573,12 @@ e_info_server_input_touchgen(int idx, int x, int y, int state) return E_INFO_INPUT_RESULT_NONE; } +char * +e_info_server_input_mousegen(int button, int x, int y, int state) +{ + if (_e_info_input.gen.fd < 0) return "Initialize device first"; + + _e_info_input_mousegen(button, 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 3cc8ea140a..5fffce4d95 100644 --- a/src/bin/e_info_server_input.h +++ b/src/bin/e_info_server_input.h @@ -7,5 +7,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); +char *e_info_server_input_mousegen(int button, 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 0349a5bb82..ad8309a19d 100644 --- a/src/bin/e_info_shared_types.h +++ b/src/bin/e_info_shared_types.h @@ -297,6 +297,15 @@ typedef enum E_INFO_EVENT_STATE_ALL } E_Info_Event_State; +typedef enum +{ + E_INFO_BUTTON_LEFT = 0, + E_INFO_BUTTON_RIGHT, + E_INFO_BUTTON_MIDDLE, + E_INFO_BUTTON_WHEEL, + E_INFO_BUTTON_HWHEEL +} E_Info_Button; + #define E_INFO_INPUT_RESULT_NONE "None" /* -------------------------------------------------------------------------- */