add a info tool enlightenment_info showing clients list in stack order 28/39328/4
authorDuna Oh <duna.oh@samsung.com>
Wed, 13 May 2015 06:18:43 +0000 (15:18 +0900)
committerDuna Oh <duna.oh@samsung.com>
Wed, 13 May 2015 08:17:35 +0000 (17:17 +0900)
Change-Id: I2073fb8d20930376b9578bdd78db007b7254a0b3
Signed-off-by: Duna Oh <duna.oh@samsung.com>
configure.ac
src/bin/Makefile.mk
src/bin/e_info.c [new file with mode: 0644]

index ffd2ef4aeb073985a44357eaae9f8ed975ac770a..55ba0bfc0a30a971520767ee077ad0125e8d0d27 100644 (file)
@@ -604,6 +604,12 @@ PKG_CHECK_MODULES(E_OPEN, [
   efreet-mime >= ${efl_version}
 ])
 
+PKG_CHECK_MODULES(E_INFO, [
+  eina >= ${efl_version}
+  ecore >= ${efl_version}
+  eldbus >= ${efl_version}
+])
+
 e_libs="$E_LIBS $LIBINTL $fnmatch_libs $execinfo_libs"
 e_cflags="-DUSE_E_CONFIG_H $E_CFLAGS -D_F_ZONE_WINDOW_ROTATION_ -D_F_E_VIRTUAL_KEYBOARD_TYPE_ -D_F_E_CLIENT_NEW_CLIENT_POST_HOOK_ -D_F_E_COMP_OBJECT_INTERCEPT_HOOK_ -D_F_TRANSIENT_FOR_PATCH -D_F_DISABLE_BACKLIGHT_MOD_SUPPORT"
 e_configflags="-DUSE_E_CONFIG_H -D_F_ZONE_WINDOW_ROTATION_ -D_F_E_VIRTUAL_KEYBOARD_TYPE_ -D_F_E_CLIENT_NEW_CLIENT_POST_HOOK_ -D_F_E_COMP_OBJECT_INTERCEPT_HOOK_ -D_F_TRANSIENT_FOR_PATCH -D_F_DISABLE_BACKLIGHT_MOD_SUPPORT"
index 4b0d13fe9fb93a0f290a88c2bf151e1f8c08e4e7..cf35f1e93102d59211869479eb80f5d7d12b9498 100644 (file)
@@ -23,7 +23,8 @@ src/bin/enlightenment \
 src/bin/enlightenment_imc \
 src/bin/enlightenment_start \
 src/bin/enlightenment_filemanager \
-src/bin/enlightenment_open
+src/bin/enlightenment_open \
+src/bin/enlightenment_info
 
 internal_bindir = $(libdir)/enlightenment/utils
 internal_bin_PROGRAMS = \
@@ -459,6 +460,12 @@ src/bin/e_static_grab.c
 src_bin_enlightenment_static_grabber_LDADD = @E_GRABBER_LIBS@
 src_bin_enlightenment_static_grabber_CPPFLAGS = @E_GRABBER_CFLAGS@
 
+src_bin_enlightenment_info_SOURCES = \
+src/bin/e.h \
+src/bin/e_info.c
+src_bin_enlightenment_info_LDADD = @E_INFO_LIBS@
+src_bin_enlightenment_info_CPPFLAGS = $(E_CPPFLAGS) @E_INFO_CFLAGS@
+
 include src/bin/e_fm/Makefile.mk
 
 # HACK! why install-data-hook? install-exec-hook is run after bin_PROGRAMS
diff --git a/src/bin/e_info.c b/src/bin/e_info.c
new file mode 100644 (file)
index 0000000..a7b07c5
--- /dev/null
@@ -0,0 +1,222 @@
+#include "e.h"
+
+typedef struct _E_Test_Info E_Test_Info;
+typedef struct _E_Win_Info E_Win_Info;
+
+struct _E_Test_Info
+{
+   Eina_List    *win_list;
+   Eldbus_Proxy *proxy;
+};
+
+struct _E_Win_Info
+{
+   uint64_t     id;         // native window id
+   const char  *name;       // name of client window
+   int          x, y, w, h; // geometry
+   int          layer;      // value of E_Layer
+   int          vis;        // visibility
+   int          alpha;      // alpha window
+};
+
+E_Win_Info *
+e_win_info_add(Ecore_Window id,
+               Eina_Bool alpha,
+               const char *name,
+               int x, int y,
+               int w, int h,
+               int layer,
+               int visible)
+{
+   E_Win_Info *win = NULL;
+
+   win = E_NEW(E_Win_Info, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
+
+   win->id = id;
+   win->name = eina_stringshare_add(name);
+   win->x = x;
+   win->y = y;
+   win->w = w;
+   win->h = h;
+   win->layer = layer;
+   win->alpha = alpha;
+   win->vis = visible;
+
+   return win;
+}
+
+void
+e_win_info_del(E_Win_Info *win)
+{
+   EINA_SAFETY_ON_NULL_RETURN(win);
+
+   if (win->name)
+     eina_stringshare_del(win->name);
+
+   E_FREE(win);
+}
+
+static void
+_cb_method_get_clients(void *data,
+                       const Eldbus_Message *msg,
+                       Eldbus_Pending *p EINA_UNUSED)
+{
+   const char *name = NULL, *text = NULL;
+   Eldbus_Message_Iter *array, *ec;
+   uint64_t target_win = 0;
+   E_Test_Info *test_info = data;
+   Eina_Bool res;
+
+   res = eldbus_message_error_get(msg, &name, &text);
+   EINA_SAFETY_ON_TRUE_GOTO(res, finish);
+
+   res = eldbus_message_arguments_get(msg, "ua(usiiiiibb)", &target_win, &array);
+   EINA_SAFETY_ON_FALSE_GOTO(res, finish);
+
+   while (eldbus_message_iter_get_and_next(array, 'r', &ec))
+     {
+        const char *win_name;
+        int x, y, w, h, layer;
+        Eina_Bool visible, alpha;
+        Ecore_Window id;
+        E_Win_Info *win = NULL;
+        res = eldbus_message_iter_arguments_get(ec,
+                                                "usiiiiibb",
+                                                &id,
+                                                &win_name,
+                                                &x,
+                                                &y,
+                                                &w,
+                                                &h,
+                                                &layer,
+                                                &visible,
+                                                &alpha);
+        if (!res)
+          {
+             printf("Failed to get win info\n");
+             continue;
+          }
+
+        win = e_win_info_add(id, alpha, win_name, x, y, w, h, layer, visible);
+        test_info->win_list = eina_list_append(test_info->win_list, win);
+     }
+   data = test_info;
+
+finish:
+   if ((name) || (text))
+     {
+        printf("errname:%s errmsg:%s\n", name, text);
+     }
+
+   ecore_main_loop_quit();
+}
+
+Eina_List *
+e_win_info_list_get(E_Test_Info *test_info)
+{
+   Eldbus_Pending *p;
+   p = eldbus_proxy_call(test_info->proxy,
+                         "GetClients",
+                         _cb_method_get_clients,
+                         test_info,
+                         -1,
+                         "");
+   EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
+
+   ecore_main_loop_begin();
+
+   return test_info->win_list;
+}
+
+static void
+_print_usage()
+{
+   printf("Options:\n"
+        "\t-topvwins\n"
+        "\t\tPrint top visible windows\n");
+   exit(0);
+}
+
+static void
+_print_stack_info(E_Test_Info *test_info)
+{
+   E_Win_Info *win;
+   Eina_List *list = NULL, *l;
+
+   EINA_SAFETY_ON_NULL_RETURN(test_info);
+
+   list = e_win_info_list_get(test_info);
+   EINA_SAFETY_ON_NULL_GOTO(list, cleanup);
+
+   printf("%d Top level windows\n", eina_list_count(list));
+   printf("-------------------------[ topvwins ]------------------------------\n");
+   printf("No   PID     w     h     x     y   Depth         Title    map state\n");
+   printf("-------------------------------------------------------------------\n");
+   int i=0;
+   EINA_LIST_FOREACH(list, l, win)
+     {
+        if (!win) return;
+        i++;
+        printf("%3d %"PRIu64" %5d %5d %5d %5d %5d ", i, win->id, win->w, win->h, win->x, win->y, win->alpha? 32:24);
+        printf("%15s %11s\n", win->name?:"No Name", win->vis? "Viewable":"NotViewable");
+     }
+cleanup:
+   E_FREE_LIST(list, e_win_info_del);
+}
+
+int
+main(int argc, char **argv)
+{
+   int res;
+   E_Test_Info * test_info;
+   Eldbus_Connection *conn;
+   Eldbus_Object     *obj;
+
+   test_info = E_NEW(E_Test_Info, 1);
+   EINA_SAFETY_ON_NULL_GOTO(test_info, err);
+
+   res = eldbus_init();
+   EINA_SAFETY_ON_FALSE_GOTO((res > 0), err);
+
+   conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
+   if (!conn)
+     {
+        printf("Can't get dbus connection.");
+        goto err;
+     }
+
+   obj = eldbus_object_get(conn,
+                           "org.enlightenment.wm",
+                           "/org/enlightenment/wm");
+   if (!obj)
+     {
+        printf("Can't get dbus object.");
+        goto err;
+     }
+
+   test_info->proxy = eldbus_proxy_get(obj, "org.enlightenment.wm.Test");
+   if (!test_info->proxy)
+     {
+        printf("Can't get dbus proxy.");
+        goto err;
+     }
+
+   if (argv[1] && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help")))
+     _print_usage();
+   else if (!strcmp(argv[1], "-topvwins"))
+     _print_stack_info(test_info);
+
+   eldbus_proxy_unref(test_info->proxy);
+   eldbus_object_unref(obj);
+   eldbus_connection_unref(conn);
+   eldbus_shutdown();
+
+   E_FREE(test_info);
+   return 0;
+
+err:
+   E_FREE(test_info);
+
+   return -1;
+}