[e_info] add "-int", "-name" and "-pid" options for the wininfo
authorKonstantin Drabeniuk <k.drabeniuk@samsung.com>
Tue, 16 May 2017 09:57:46 +0000 (12:57 +0300)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 25 May 2017 23:26:07 +0000 (08:26 +0900)
Change-Id: I84cffde65a4b21ef4f0f843f9bef180df4e38eca
Signed-off-by: Konstantin Drabeniuk <k.drabeniuk@samsung.com>
src/bin/e_info_client.c
src/bin/e_info_server.c

index 09be212bd252274229c8113a503326f948b4fc9b..fad931626b2418b90cac03fe3a72ee65396082eb 100644 (file)
@@ -293,6 +293,58 @@ _e_get_window_name(uint64_t win)
    return win_name;
 }
 
+static void
+_e_message_get_windows(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
+{
+   const char *name = NULL, *text = NULL;
+   Eina_Bool res;
+   Eldbus_Message_Iter *array_of_windows;
+   uint64_t win;
+   Eina_List **win_list = data;
+
+   res = eldbus_message_error_get(msg, &name, &text);
+   EINA_SAFETY_ON_TRUE_GOTO(res, finish);
+
+   res = eldbus_message_arguments_get(msg, "at", &array_of_windows);
+   EINA_SAFETY_ON_FALSE_GOTO(res, finish);
+
+   while (eldbus_message_iter_get_and_next(array_of_windows, 't', &win))
+     {
+        *win_list = eina_list_append(*win_list, (void *)((Ecore_Window)win));
+     }
+
+   ecore_main_loop_quit();
+
+   return;
+
+finish:
+   if ((name) || (text))
+     {
+        printf("errname:%s errmsg:%s\n", name, text);
+     }
+
+   ecore_main_loop_quit();
+}
+
+const static int _E_GET_WINDOWS_NAME_MODE = 1;
+const static int _E_GET_WINDOWS_PID_MODE = 2;
+
+static Eina_List *
+_e_get_windows(int mode, char *value)
+{
+   Eldbus_Pending *p;
+   Eina_List *win_list = NULL;
+
+   p = eldbus_proxy_call(e_info_client.proxy, "get_windows",
+                         _e_message_get_windows,
+                         &win_list, -1, "is", mode, value);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
+
+   ecore_main_loop_begin();
+
+   return win_list;
+}
+
 static E_Win_Info *
 _e_win_info_new(Ecore_Window id, uint32_t res_id, int pid, Eina_Bool alpha, int opaque, const char *name, int x, int y, int w, int h, int layer, int visible, int visibility, int iconic, int frame_visible, int focused, int hwc, int pl_zpos, Ecore_Window parent_id, const char *layer_name)
 {
@@ -2828,6 +2880,8 @@ usage:
    printf("Usage: enlightenment_info %s", KILL_USAGE);
 }
 
+static int window_id_format_dec;
+
 static void
 _e_info_client_cb_wininfo(const Eldbus_Message *msg)
 {
@@ -2869,8 +2923,12 @@ _e_info_client_cb_wininfo(const Eldbus_Message *msg)
                                       &redirected);
    EINA_SAFETY_ON_FALSE_GOTO(res, finish);
 
-   printf("\n   Parent id: 0x%lx\n"
-          "   Resource id: %u\n"
+   if (window_id_format_dec)
+     printf("\n   Parent id: %lu\n", (unsigned long)parent_id);
+   else
+     printf("\n   Parent id: 0x%lx\n", (unsigned long)parent_id);
+
+   printf("   Resource id: %u\n"
           "   PID: %d\n"
           "   X: %d\n"
           "   Y: %d\n"
@@ -2886,7 +2944,7 @@ _e_info_client_cb_wininfo(const Eldbus_Message *msg)
           "   Frame visible: %d\n"
           "   Redirect State: %s\n"
           "   Layer name: %s\n",
-          (unsigned long)parent_id, res_id, pid, x, y, w, h, border_size, alpha ? 32 : 24,
+          res_id, pid, x, y, w, h, border_size, alpha ? 32 : 24,
           focused, opaque, obscured, iconic, visible ? "Visible" : "Not visible",
           frame_visible, redirected ? "yes" : "no", layer_name);
    printf("   PL@ZPos:");
@@ -2933,7 +2991,11 @@ _e_info_client_cb_wininfo_tree(const Eldbus_Message *msg)
                                       &pwin, &pname, &num_children, &array_of_children);
    EINA_SAFETY_ON_FALSE_GOTO(res, finish);
 
-   printf("\n   Parent window id: 0x%lx \"%s\"\n", (unsigned long)pwin, pname);
+   if (window_id_format_dec)
+     printf("\n   Parent window id: %lu \"%s\"\n", (unsigned long)pwin, pname);
+   else
+     printf("\n   Parent window id: 0x%lx \"%s\"\n", (unsigned long)pwin, pname);
+
    printf ("      %d child%s%s\n", num_children, num_children == 1 ? "" : "ren",
       num_children ? ":" : ".");
 
@@ -2952,7 +3014,10 @@ _e_info_client_cb_wininfo_tree(const Eldbus_Message *msg)
         EINA_SAFETY_ON_FALSE_GOTO(res, finish);
 
         for (j = 0; j <= level; j++) printf ("   ");
-        printf("0x%lx \"%s\":", (unsigned long)child_win, child_name);
+        if (window_id_format_dec)
+          printf("%lu \"%s\":", (unsigned long)child_win, child_name);
+        else
+          printf("0x%lx \"%s\":", (unsigned long)child_win, child_name);
         printf (" %dx%d+%d+%d", w, h, x, y);
         if (hwc > 0) printf(" hwc@%i", pl_zpos);
         else if (!hwc) printf(" comp@%i", pl_zpos);
@@ -2974,14 +3039,56 @@ finish:
      }
 }
 
+static Eina_Bool
+_e_info_client_display_wininfo(uint64_t win, int children, int tree, int stats)
+{
+   Eina_Bool res;
+   char *win_name;
+
+   win_name = _e_get_window_name(win);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(win_name, EINA_FALSE);
+
+   if (window_id_format_dec)
+     printf("\nwininfo: Window id: %lu \"%s\"\n", (unsigned long)win, win_name);
+   else
+     printf("\nwininfo: Window id: 0x%lx \"%s\"\n", (unsigned long)win, win_name);
+
+   free(win_name);
+
+   if ((children || tree))
+     {
+        res = _e_info_client_eldbus_message_with_args("wininfo_tree",
+                                                      _e_info_client_cb_wininfo_tree,
+                                                      VALUE_TYPE_REQUEST_FOR_WININFO_TREE,
+                                                      win, tree);
+        EINA_SAFETY_ON_FALSE_RETURN_VAL(res, EINA_FALSE);
+     }
+   else
+     stats = 1;
+
+   if (stats)
+     {
+        res = _e_info_client_eldbus_message_with_args("wininfo",
+                                                      _e_info_client_cb_wininfo,
+                                                      VALUE_TYPE_REQUEST_FOR_WININFO,
+                                                      win);
+        EINA_SAFETY_ON_FALSE_RETURN_VAL(res, EINA_FALSE);
+     }
+
+   return EINA_TRUE;
+}
+
 #define WININFO_USAGE \
   "[-options ...]\n\n" \
   "where options include:\n" \
-  "\t-help        : print this message.\n" \
-  "\t-children    : print parent and child identifiers.\n" \
-  "\t-tree        : print children identifiers recursively.\n" \
-  "\t-stats       : print window geometry [DEFAULT]\n" \
-  "\t-id windowid : use the window with the specified id\n" \
+  "\t-help             : print this message.\n" \
+  "\t-children         : print parent and child identifiers.\n" \
+  "\t-tree             : print children identifiers recursively.\n" \
+  "\t-stats            : print window geometry [DEFAULT]\n" \
+  "\t-id windowid      : use the window with the specified id\n" \
+  "\t-name windowname  : use the window with the specified name\n" \
+  "\t-pid windowpid    : use the window with the specified id\n" \
+  "\t-int              : print window id in decimal\n" \
 
 static void
 _e_info_client_proc_wininfo(int argc, char **argv)
@@ -2989,48 +3096,99 @@ _e_info_client_proc_wininfo(int argc, char **argv)
    Eina_Bool res;
    uint64_t win = 0;
    int i, children = 0, tree = 0, stats = 0;
-   char *win_name;
+   char *name = NULL, *pid = NULL;
+   Eina_List *win_list = NULL, *l;
 
    /* Handle our command line arguments */
-   for (i = 2; i < argc; i++) {
-     if (eina_streq (argv[i], "-help"))
-       goto usage;
-     if (eina_streq (argv[i], "-children"))
-       {
-          children = 1;
-          continue;
-       }
-     if (eina_streq (argv[i], "-tree"))
-       {
-          tree = 1;
-          continue;
-       }
-     if (eina_streq (argv[i], "-stats"))
-       {
-          stats = 1;
-          continue;
-       }
-     if (eina_streq (argv[i], "-id"))
-       {
-          if (++i >= argc)
-            {
-               printf("Error: -id requires argument\n");
-               goto usage;
-            }
-
-          if (strlen(argv[i]) >= 2 && argv[i][0] == '0' && argv[i][1] == 'x')
-            res = _util_string_to_ulong(argv[i], (unsigned long *)&win, 16);
-          else
-            res = _util_string_to_ulong(argv[i], (unsigned long *)&win, 10);
-          EINA_SAFETY_ON_FALSE_GOTO(res, usage);
-
-          continue;
-      }
+   for (i = 2; i < argc; i++)
+     {
+        if (eina_streq(argv[i], "-help"))
+          goto usage;
 
-     goto usage;
-   }
+        if (eina_streq (argv[i], "-children"))
+          {
+             children = 1;
+             continue;
+          }
+
+        if (eina_streq(argv[i], "-tree"))
+          {
+             tree = 1;
+             continue;
+          }
+
+        if (eina_streq(argv[i], "-stats"))
+          {
+             stats = 1;
+             continue;
+          }
 
-   if (!win)
+        if (eina_streq(argv[i], "-id"))
+          {
+             if (++i >= argc || (argv[i][0] < '0' || argv[i][0] > '9'))
+               {
+                  printf("Error: -id requires argument\n");
+                  goto usage;
+               }
+
+             if (strlen(argv[i]) >= 2 && argv[i][0] == '0' && argv[i][1] == 'x')
+               res = _util_string_to_ulong(argv[i], (unsigned long *)&win, 16);
+             else
+               res = _util_string_to_ulong(argv[i], (unsigned long *)&win, 10);
+
+             EINA_SAFETY_ON_FALSE_GOTO(res, usage);
+
+             continue;
+          }
+
+        if (eina_streq(argv[i], "-name"))
+          {
+             if (++i >= argc)
+               {
+                  printf("Error: -name requires argument\n");
+                  goto usage;
+               }
+
+             name = argv[i];
+             continue;
+          }
+
+        if (eina_streq(argv[i], "-pid"))
+          {
+             if (++i >= argc || (argv[i][0] < '0' || argv[i][0] > '9'))
+               {
+                  printf("Error: -name requires argument\n");
+                  goto usage;
+               }
+
+             pid = argv[i];
+             continue;
+          }
+        if (eina_streq (argv[i], "-int"))
+          {
+             window_id_format_dec = 1;
+             continue;
+          }
+
+        goto usage;
+     }
+
+   if (!win && (name || pid))
+     {
+        if (name)
+          win_list = _e_get_windows(_E_GET_WINDOWS_NAME_MODE, name);
+        else
+          win_list = _e_get_windows(_E_GET_WINDOWS_PID_MODE, pid);
+
+        if (!win_list)
+          {
+             printf("Error: cannot get windows\n");
+             return;
+          }
+     }
+
+
+   if (!win && !win_list)
      {
         printf("Please select the window about which you\n"
                "would like information by clicking the\n"
@@ -3042,33 +3200,27 @@ _e_info_client_proc_wininfo(int argc, char **argv)
           }
      }
 
-   win_name = _e_get_window_name(win);
-   EINA_SAFETY_ON_NULL_RETURN(win_name);
-
-   printf("\nwininfo: Window id: 0x%lx \"%s\"\n", (unsigned long)win, win_name);
-
-   free(win_name);
-
-   if ((children || tree))
+   if (win)
      {
-        res = _e_info_client_eldbus_message_with_args("wininfo_tree",
-                                                      _e_info_client_cb_wininfo_tree,
-                                                      VALUE_TYPE_REQUEST_FOR_WININFO_TREE,
-                                                      win, tree);
+        res = _e_info_client_display_wininfo(win, children, tree, stats);
         EINA_SAFETY_ON_FALSE_RETURN(res);
      }
    else
-     stats = 1;
-
-   if (stats)
      {
-        res = _e_info_client_eldbus_message_with_args("wininfo",
-                                                      _e_info_client_cb_wininfo,
-                                                      VALUE_TYPE_REQUEST_FOR_WININFO,
-                                                      win);
-        EINA_SAFETY_ON_FALSE_RETURN(res);
+        for(l = win_list; l; l = eina_list_next(l))
+          {
+             uint64_t win;
+
+             win = (uint64_t)((Ecore_Window)eina_list_data_get(l));
+             res = _e_info_client_display_wininfo(win, children, tree, stats);
+             EINA_SAFETY_ON_FALSE_GOTO(res, finish);
+          }
      }
 
+finish:
+   if (win_list)
+     eina_list_free(win_list);
+
    return;
 
 usage:
index 35ef8fef6b60caca4ddd70caee0df932863e3a46..5486aeeeb36c29b6ad546bf276e3d67081e68313 100755 (executable)
@@ -3214,6 +3214,99 @@ finish:
    return reply;
 }
 
+static Eldbus_Message *
+_e_info_server_cb_get_windows(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+   const static int _E_GET_WINDOWS_NAME_MODE = 1;
+   const static int _E_GET_WINDOWS_PID_MODE = 2;
+   Eldbus_Message *reply;
+   Eldbus_Message_Iter *iter;
+   Eina_Bool res;
+   E_Client *ec;
+   char *value;
+   uint32_t mode;
+   int count = 0;
+   Eldbus_Message_Iter *array_of_windows;
+   Evas_Object *o;
+   pid_t pid;
+
+   res = eldbus_message_arguments_get(msg, "is", &mode, &value);
+   if (res != EINA_TRUE)
+     {
+        return eldbus_message_error_new(msg, GET_CALL_MSG_ARG_ERR,
+                      "get_windows: an attempt to get arguments from method call message failed");
+     }
+
+   if (mode == _E_GET_WINDOWS_PID_MODE)
+     {
+        if (strlen(value) >= 2 && value[0] == '0' && value[1] == 'x')
+          res = e_util_string_to_int(value, &pid, 16);
+        else
+          res = e_util_string_to_int(value, &pid, 10);
+
+       if (res == EINA_FALSE)
+         return eldbus_message_error_new(msg, INVALID_ARGS,
+                                       "get_windows: invalid input arguments");
+     }
+
+   reply = eldbus_message_method_return_new(msg);
+   iter = eldbus_message_iter_get(reply);
+
+   eldbus_message_iter_arguments_append(iter, "at", &array_of_windows);
+
+   for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
+     {
+        const char *ec_name, *find;
+        Ecore_Window win;
+
+        ec = evas_object_data_get(o, "E_Client");
+        if (!ec) continue;
+
+        ec_name = e_client_util_name_get(ec) ?: "NO NAME";
+
+        if (mode == _E_GET_WINDOWS_NAME_MODE)
+          {
+             find = strstr(ec_name, (const char *)value);
+
+             if (!find)
+               continue;
+          }
+        else if (mode == _E_GET_WINDOWS_PID_MODE)
+          {
+             pid_t ec_pid = -1;
+
+             ec_pid = ec->netwm.pid;
+             if (ec_pid <= 0)
+               {
+                  if (ec->comp_data)
+                    {
+                       E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
+                       if (cdata->surface)
+                       wl_client_get_credentials(wl_resource_get_client(cdata->surface), &ec_pid, NULL, NULL);
+                    }
+               }
+             if (ec_pid != pid)
+               continue;
+          }
+
+        win = e_client_util_win_get(ec);
+
+        count++;
+
+        eldbus_message_iter_arguments_append(array_of_windows, "t", win);
+     }
+
+   eldbus_message_iter_container_close(iter, array_of_windows);
+
+   if (count)
+     return reply;
+
+   eldbus_message_unref(reply);
+
+   return eldbus_message_error_new(msg, WIN_NOT_EXIST,
+                              "get_windows: specified window(s) doesn't exist");
+}
+
 static Eldbus_Message *
 _e_info_server_cb_get_window_name(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
 {
@@ -3432,6 +3525,7 @@ static const Eldbus_Method methods[] = {
    { "get_win_under_touch", NULL, ELDBUS_ARGS({"i", "result"}), _e_info_server_cb_get_win_under_touch, 0 },
    { "kill_client", ELDBUS_ARGS({VALUE_TYPE_REQUEST_FOR_KILL, "window"}), ELDBUS_ARGS({"a"VALUE_TYPE_REPLY_KILL, "kill result"}), _e_info_server_cb_kill_client, 0 },
    { "get_window_name", ELDBUS_ARGS({"t", "window"}), ELDBUS_ARGS({"s", "window name"}), _e_info_server_cb_get_window_name, 0 },
+   { "get_windows", ELDBUS_ARGS({"is", "mode, value"}), ELDBUS_ARGS({"at", "array_of_windows"}), _e_info_server_cb_get_windows, 0 },
    { "wininfo", ELDBUS_ARGS({VALUE_TYPE_REQUEST_FOR_WININFO, "window"}), ELDBUS_ARGS({VALUE_TYPE_REPLY_WININFO, "window info"}), _e_info_server_cb_wininfo, 0 },
    { "wininfo_tree", ELDBUS_ARGS({VALUE_TYPE_REQUEST_FOR_WININFO_TREE, "wininfo_tree"}), ELDBUS_ARGS({VALUE_TYPE_REPLY_WININFO_TREE, "window tree info"}), _e_info_server_cb_wininfo_tree, 0 },
    { NULL, NULL, NULL, NULL, 0 }