e_info: add mouse event generation utility 08/232008/6
authorjeon <jhyuni.kang@samsung.com>
Mon, 27 Apr 2020 09:08:51 +0000 (18:08 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Mon, 27 Apr 2020 11:05:45 +0000 (11:05 +0000)
Change-Id: I0d13ed848ffd5ef80e63fe03ccaf7cbd0d93be61

src/bin/e_info_client.c
src/bin/e_info_server.c
src/bin/e_info_server_input.c
src/bin/e_info_server_input.h
src/bin/e_info_shared_types.h

index e9bf97de916fc2c65ee3c614193520961646248f..5fb088570ccfe9b6185f25f255aae4f97d89e5c5 100644 (file)
@@ -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;
index 96052cfdd6326b6b0ae46f560d0549b097182528..c986d233a733493c515afec85ae99f97597bb8e3 100644 (file)
@@ -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 }
 };
index 2eeb28668e1edf5d1bbeff0dbce22d9ec1afd19c..e55dae329855157811b5766b5281584079c8dad2 100644 (file)
@@ -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;
+}
index 3cc8ea140a098e4d94cd0e89d4b754b5856072a8..5fffce4d95dfc302eb440b447aef64009b1b5167 100644 (file)
@@ -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
index 0349a5bb824b5eb5289cea2808c9cc9aca14aa87..ad8309a19d6fa2d5c40b27a9e89d26f00daf617a 100644 (file)
@@ -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"
 
 /* -------------------------------------------------------------------------- */