add shot_topvwins to enlightenment_info 58/42858/1
authorBoram Park <boram1288.park@samsung.com>
Wed, 1 Jul 2015 05:45:03 +0000 (14:45 +0900)
committerBoram Park <boram1288.park@samsung.com>
Fri, 3 Jul 2015 07:42:37 +0000 (16:42 +0900)
Change-Id: I14520da2eb4d7644d3fafd4794ac3ced9f68734d

configure.ac
packaging/enlightenment.spec
src/bin/Makefile.mk
src/bin/e_includes.h
src/bin/e_info.c [deleted file]
src/bin/e_info_client.c [new file with mode: 0644]
src/bin/e_info_server.c [new file with mode: 0644]
src/bin/e_info_server.h [new file with mode: 0644]
src/bin/e_main.c

index c1d3a09..1d74877 100644 (file)
@@ -565,6 +565,7 @@ e_requires="\
   elementary >= $efl_version \
   emotion >= $efl_version \
   $eeze_mount \
+  libtbm \
   $udisks_mount \
   $device_libs"
 if test "x${e_cv_want_wayland_only}" != "xyes"; then
index aa0119d..41f1a06 100644 (file)
@@ -36,6 +36,7 @@ BuildRequires:  pkgconfig(elementary)
 BuildRequires:  pkgconfig(ice)
 BuildRequires:  pkgconfig(libudev)
 BuildRequires:  pkgconfig(udev)
+BuildRequires:  pkgconfig(libtbm)
 %if %{with x}
 BuildRequires:  pkgconfig(x11)
 BuildRequires:  pkgconfig(xext)
index 1b6c6c6..2153b27 100644 (file)
@@ -378,6 +378,7 @@ endif
 
 if HAVE_WAYLAND
 enlightenment_src += \
+src/bin/e_info_server.c \
 src/bin/e_drm_buffer_pool.c \
 src/bin/e_drm_buffer_pool_server_protocol.c \
 src/bin/e_uuid_store.c \
@@ -466,7 +467,7 @@ 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/e_info_client.c
 src_bin_enlightenment_info_LDADD = @E_INFO_LIBS@
 src_bin_enlightenment_info_CPPFLAGS = $(E_CPPFLAGS) @E_INFO_CFLAGS@
 
index e5873db..cc0bc03 100644 (file)
@@ -43,6 +43,7 @@
 #include "e_ipc_codec.h"
 #include "e_test.h"
 #include "e_test_helper.h"
+#include "e_info_server.h"
 #include "e_prefix.h"
 #include "e_datastore.h"
 #include "e_msg.h"
diff --git a/src/bin/e_info.c b/src/bin/e_info.c
deleted file mode 100644 (file)
index fb77d19..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-#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,
-                         "GetWindowInfo",
-                         _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;
-
-   if (argc <= 1)
-     {
-        _print_usage();
-        return 0;
-     }
-
-   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 (!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);
-     }
-   else
-     {
-        _print_usage();
-     }
-
-   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;
-}
diff --git a/src/bin/e_info_client.c b/src/bin/e_info_client.c
new file mode 100644 (file)
index 0000000..5443814
--- /dev/null
@@ -0,0 +1,438 @@
+#include "e.h"
+#include <time.h>
+#include <dirent.h>
+
+typedef void (*E_Info_Message_Cb)(const Eldbus_Message *msg);
+
+typedef struct _E_Info_Client
+{
+   /* eldbus */
+   int eldbus_init;
+   Eldbus_Proxy *proxy;
+   Eldbus_Connection *conn;
+   Eldbus_Object  *obj;
+
+   /* topvwins */
+   Eina_List    *win_list;
+} E_Info_Client;
+
+typedef 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;
+
+static E_Info_Client e_info_client;
+
+static Eina_Bool
+_e_info_client_eldbus_message(const char *method, E_Info_Message_Cb cb);
+static Eina_Bool
+_e_info_client_eldbus_message_with_args(const char *method, E_Info_Message_Cb cb,
+                                        const char *signature, ...);
+
+static E_Win_Info *
+_e_win_info_new(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;
+}
+
+static void
+_e_win_info_free(E_Win_Info *win)
+{
+   EINA_SAFETY_ON_NULL_RETURN(win);
+
+   if (win->name)
+     eina_stringshare_del(win->name);
+
+   E_FREE(win);
+}
+
+static void
+_get_window_info_cb(const Eldbus_Message *msg)
+{
+   const char *name = NULL, *text = NULL;
+   Eldbus_Message_Iter *array, *ec;
+   Eina_Bool res;
+
+   res = eldbus_message_error_get(msg, &name, &text);
+   EINA_SAFETY_ON_TRUE_GOTO(res, finish);
+
+   res = eldbus_message_arguments_get(msg, "a(usiiiiibb)", &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_new(id, alpha, win_name, x, y, w, h, layer, visible);
+        e_info_client.win_list = eina_list_append(e_info_client.win_list, win);
+     }
+
+finish:
+   if ((name) || (text))
+     {
+        printf("errname:%s errmsg:%s\n", name, text);
+     }
+}
+
+static void
+_e_info_client_proc_topvwins(int argc, char **argv)
+{
+   E_Win_Info *win;
+   Eina_List *l;
+   int i = 0;
+
+   if (!_e_info_client_eldbus_message("get_window_info", _get_window_info_cb))
+     return;
+
+   printf("%d Top level windows\n", eina_list_count(e_info_client.win_list));
+   printf("-------------------------[ topvwins ]------------------------------\n");
+   printf("No   PID     w     h     x     y   Depth         Title    map state\n");
+   printf("-------------------------------------------------------------------\n");
+
+   if (!e_info_client.win_list)
+     {
+        printf("no window\n");
+        return;
+     }
+
+   EINA_LIST_FOREACH(e_info_client.win_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");
+     }
+
+   E_FREE_LIST(e_info_client.win_list, _e_win_info_free);
+}
+
+static char*
+_directory_make(char *path)
+{
+   char dir[PATH_MAX], curdir[PATH_MAX], stamp[PATH_MAX];
+   time_t timer;
+   struct tm *t, *buf;
+   char *fullpath;
+   DIR *dp;
+
+   timer = time(NULL);
+
+   buf = calloc (1, sizeof (struct tm));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(buf, NULL);
+
+   t = localtime_r(&timer, buf);
+   if (!t)
+     {
+        free(buf);
+        printf("fail to get local time\n");
+        return NULL;
+     }
+
+   fullpath = (char*) calloc(1, PATH_MAX*sizeof(char));
+   if (!fullpath)
+     {
+        free(buf);
+        printf("fail to alloc pathname memory\n");
+        return NULL;
+     }
+
+   if (path && path[0] == '/')
+     snprintf(dir, PATH_MAX, "%s", path);
+   else
+     {
+        char *temp = getcwd(curdir, PATH_MAX);
+        if (!temp)
+          {
+             free(buf);
+             return NULL;
+          }
+        if (path)
+          {
+             if (strlen(curdir) == 1 && curdir[0] == '/')
+               snprintf(dir, PATH_MAX, "/%s", path);
+             else
+               snprintf(dir, PATH_MAX, "%s/%s", curdir, path);
+          }
+        else
+          snprintf(dir, PATH_MAX, "%s", curdir);
+     }
+
+   if (!(dp = opendir (dir)))
+     {
+        printf("not exist: %s\n", dir);
+        return NULL;
+     }
+   else
+      closedir (dp);
+
+   /* make the folder for the result of xwd files */
+   snprintf(stamp, PATH_MAX, "%04d%02d%02d.%02d%02d%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+
+   if (strlen(dir) == 1 && dir[0] == '/')
+     snprintf(fullpath, PATH_MAX, "/topvwins-%s", stamp);
+   else
+     snprintf(fullpath, PATH_MAX, "%s/topvwins-%s", dir, stamp);
+
+   free (buf);
+
+   if ((mkdir(fullpath, 0755)) < 0)
+     {
+        printf("fail: mkdir '%s'\n", fullpath);
+        return NULL;
+     }
+
+   printf("directory: %s\n", fullpath);
+
+   return fullpath;
+}
+
+static void
+_e_info_client_proc_shot_topvwins(int argc, char **argv)
+{
+   char *directory = _directory_make(argv[2]);
+   EINA_SAFETY_ON_NULL_RETURN(directory);
+
+   if (!_e_info_client_eldbus_message_with_args("shot_topvwins", NULL, "s", directory))
+     {
+        free(directory);
+        return;
+     }
+
+   free(directory);
+}
+
+static struct
+{
+   const char *option;
+   const char *params;
+   const char *description;
+   void (*func)(int argc, char **argv);
+} procs[] =
+{
+   {
+      "topvwins", NULL,
+      "Print top visible windows",
+      _e_info_client_proc_topvwins
+   },
+   {
+      "shot_topvwins", "[directory_path]",
+      "Dump topvwins (default directory_path : current working directory)",
+      _e_info_client_proc_shot_topvwins
+   },
+};
+
+static void
+_e_info_client_eldbus_message_cb(void *data,
+                                 const Eldbus_Message *msg,
+                                 Eldbus_Pending *p EINA_UNUSED)
+{
+   E_Info_Message_Cb cb = (E_Info_Message_Cb)data;
+
+   if (cb)
+     cb(msg);
+
+   ecore_main_loop_quit();
+}
+
+static Eina_Bool
+_e_info_client_eldbus_message(const char *method, E_Info_Message_Cb cb)
+{
+   Eldbus_Pending *p;
+
+   p = eldbus_proxy_call(e_info_client.proxy, method,
+                         _e_info_client_eldbus_message_cb,
+                         cb, -1, "");
+   EINA_SAFETY_ON_NULL_RETURN_VAL(p, EINA_FALSE);
+
+   ecore_main_loop_begin();
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_info_client_eldbus_message_with_args(const char *method, E_Info_Message_Cb cb,
+                                        const char *signature, ...)
+{
+   Eldbus_Pending *p;
+   va_list ap;
+
+   va_start(ap, signature);
+   p = eldbus_proxy_vcall(e_info_client.proxy, method,
+                          _e_info_client_eldbus_message_cb,
+                          cb, -1, signature, ap);
+   va_end(ap);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(p, EINA_FALSE);
+
+   ecore_main_loop_begin();
+   return EINA_TRUE;
+}
+
+static void
+_e_info_client_eldbus_disconnect(void)
+{
+   if (e_info_client.proxy)
+     {
+        eldbus_proxy_unref(e_info_client.proxy);
+        e_info_client.proxy = NULL;
+     }
+   if (e_info_client.obj)
+     {
+        eldbus_object_unref(e_info_client.obj);
+        e_info_client.obj = NULL;
+     }
+   if (e_info_client.conn)
+     {
+        eldbus_connection_unref(e_info_client.conn);
+        e_info_client.conn = NULL;
+     }
+   if (e_info_client.eldbus_init)
+     {
+        eldbus_shutdown();
+        e_info_client.eldbus_init = 0;
+     }
+}
+
+static Eina_Bool
+_e_info_client_eldbus_connect(void)
+{
+   e_info_client.eldbus_init = eldbus_init();
+   EINA_SAFETY_ON_FALSE_GOTO(e_info_client.eldbus_init > 0, err);
+
+   e_info_client.conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
+   EINA_SAFETY_ON_NULL_GOTO(e_info_client.conn, err);
+
+   e_info_client.obj = eldbus_object_get(e_info_client.conn,
+                                         "org.enlightenment.wm",
+                                         "/org/enlightenment/wm");
+   EINA_SAFETY_ON_NULL_GOTO(e_info_client.obj, err);
+
+   e_info_client.proxy = eldbus_proxy_get(e_info_client.obj, "org.enlightenment.wm.info");
+   EINA_SAFETY_ON_NULL_GOTO(e_info_client.proxy, err);
+
+   return EINA_TRUE;
+
+err:
+   _e_info_client_eldbus_disconnect();
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_e_info_client_process(int argc, char **argv)
+{
+   int nproc = sizeof(procs) / sizeof(procs[0]);
+   int i;
+
+   for (i = 0; i < nproc; i++)
+     {
+        if (!strncmp(argv[1]+1, procs[i].option, strlen(procs[i].option)))
+          {
+             if (procs[i].func)
+               procs[i].func(argc, argv);
+
+             return EINA_TRUE;
+          }
+     }
+
+   return EINA_FALSE;
+}
+
+static void
+_e_info_client_print_usage(const char *exec)
+{
+   int nproc = sizeof(procs) / sizeof(procs[0]);
+   int i;
+
+   printf("\n");
+   printf("Usage:\n");
+   for (i = 0; i < nproc; i++)
+     printf("  %s -%s %s\n", exec, procs[i].option, (procs[i].params)?procs[i].params:"");
+   printf("\n");
+   printf("Option:\n");
+   for (i = 0; i < nproc; i++)
+     {
+        printf("  -%s\n", procs[i].option);
+        printf("      %s\n", (procs[i].description)?procs[i].description:"");
+     }
+   printf("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+   if (argc < 2 || argv[1][0] != '-')
+     {
+        _e_info_client_print_usage(argv[0]);
+        return 0;
+     }
+
+   /* connecting dbus */
+   if (!_e_info_client_eldbus_connect())
+     goto err;
+
+   if (!strcmp(argv[1], "-h") ||
+       !strcmp(argv[1], "-help") ||
+       !strcmp(argv[1], "--help"))
+     _e_info_client_print_usage(argv[0]);
+   else
+     {
+        /* handling a client request */
+        if (!_e_info_client_process(argc, argv))
+          {
+             printf("unknown option: %s\n", argv[1]);
+             _e_info_client_print_usage(argv[0]);
+          }
+     }
+
+   /* disconnecting dbus */
+   _e_info_client_eldbus_disconnect();
+   return 0;
+
+err:
+   _e_info_client_eldbus_disconnect();
+   return -1;
+}
diff --git a/src/bin/e_info_server.c b/src/bin/e_info_server.c
new file mode 100644 (file)
index 0000000..605f295
--- /dev/null
@@ -0,0 +1,211 @@
+#include "e.h"
+#include <tbm_bufmgr.h>
+
+#define BUS "org.enlightenment.wm"
+#define PATH "/org/enlightenment/wm"
+#define IFACE "org.enlightenment.wm.info"
+
+typedef struct _E_Info_Server
+{
+   Eldbus_Connection *conn;
+   Eldbus_Service_Interface *iface;
+} E_Info_Server;
+
+static E_Info_Server e_info_server;
+
+struct wl_drm;
+struct wl_drm_buffer {
+   struct wl_resource *resource;
+   struct wl_drm *drm;
+   int32_t width, height;
+   uint32_t format;
+   const void *driver_format;
+   int32_t offset[3];
+   int32_t stride[3];
+   void *driver_buffer;
+};
+
+static void
+_message_append_clients(Eldbus_Message_Iter *iter)
+{
+   Eldbus_Message_Iter *array_of_ec;
+   E_Client *ec;
+   Evas_Object *o;
+
+   eldbus_message_iter_arguments_append(iter, "a(usiiiiibb)", &array_of_ec);
+
+   // append clients.
+   for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
+     {
+        Eldbus_Message_Iter* struct_of_ec;
+        Ecore_Window win;
+
+        ec = evas_object_data_get(o, "E_Client");
+        if (!ec) continue;
+        if (e_client_util_ignored_get(ec)) continue;
+
+        win = e_client_util_win_get(ec);
+
+        eldbus_message_iter_arguments_append(array_of_ec, "(usiiiiibb)", &struct_of_ec);
+        eldbus_message_iter_arguments_append
+           (struct_of_ec, "usiiiiibb",
+            win,
+            e_client_util_name_get(ec) ?: "NO NAME",
+            ec->x, ec->y, ec->w, ec->h, ec->layer,
+            ec->visible, ec->argb);
+        eldbus_message_iter_container_close(array_of_ec, struct_of_ec);
+     }
+
+   eldbus_message_iter_container_close(iter, array_of_ec);
+}
+
+/* Method Handlers */
+static Eldbus_Message *
+_e_info_server_cb_get_window_info(const Eldbus_Service_Interface *iface EINA_UNUSED,
+                                  const Eldbus_Message *msg)
+{
+   Eldbus_Message *reply = eldbus_message_method_return_new(msg);
+
+   _message_append_clients(eldbus_message_iter_get(reply));
+
+   return reply;
+}
+
+static Eldbus_Message *
+_e_info_server_cb_shot_topvwins(const Eldbus_Service_Interface *iface EINA_UNUSED,
+                                const Eldbus_Message *msg)
+{
+   Eldbus_Message *reply = eldbus_message_method_return_new(msg);
+   const char *dir;
+   Evas_Object *o;
+
+   if (!eldbus_message_arguments_get(msg, "s", &dir))
+     {
+        ERR("Error getting arguments.");
+        return reply;
+     }
+
+   for (o = evas_object_top_get(e_comp->evas); o; o = evas_object_below_get(o))
+     {
+        E_Client *ec = evas_object_data_get(o, "E_Client");
+        char fname[PATH_MAX];
+        uint64_t win;
+        void *data = NULL;
+        int w = 0, h = 0;
+        Ecore_Evas *ee = NULL;
+        Evas_Object *img = NULL;
+
+        if (!ec) continue;
+        if (e_client_util_ignored_get(ec)) continue;
+
+        win = e_client_util_win_get(ec);
+        snprintf(fname, sizeof(fname), "%s/%llu.png", dir, win);
+
+#ifdef HAVE_WAYLAND_ONLY
+        E_Comp_Wl_Buffer *buffer = e_pixmap_resource_get(ec->pixmap);
+        if (!buffer) continue;
+
+        if (buffer->type == E_COMP_WL_BUFFER_TYPE_SHM)
+          {
+             data = wl_shm_buffer_get_data(wl_shm_buffer_get(buffer->resource));
+             w = wl_shm_buffer_get_stride(wl_shm_buffer_get(buffer->resource))/4;
+             h = wl_shm_buffer_get_height(wl_shm_buffer_get(buffer->resource));
+          }
+        else if (buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
+          {
+             struct wl_drm_buffer *drm_buffer = wl_resource_get_user_data(buffer->resource);
+             data = tbm_bo_map((tbm_bo)drm_buffer->driver_buffer, TBM_DEVICE_CPU, TBM_OPTION_READ).ptr;
+             w = drm_buffer->width;
+             h = drm_buffer->height;
+          }
+        else
+          {
+             ERR("Invalid resource:%u", wl_resource_get_id(buffer->resource));
+          }
+#endif
+
+        EINA_SAFETY_ON_NULL_GOTO(data, err);
+
+        ee = ecore_evas_buffer_new(1, 1);
+        EINA_SAFETY_ON_NULL_GOTO(ee, err);
+
+        img = evas_object_image_add(ecore_evas_get(ee));
+        EINA_SAFETY_ON_NULL_GOTO(img, err);
+
+        evas_object_image_alpha_set(img, ec->argb);
+        evas_object_image_size_set(img, w, h);
+        evas_object_image_data_set(img, data);
+        if (!evas_object_image_save(img, fname, NULL, "compress=1 quality=100"))
+          ERR("Cannot save window to '%s'", fname);
+
+err:
+#ifdef HAVE_WAYLAND_ONLY
+        if (data && buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
+          {
+             struct wl_drm_buffer *drm_buffer = wl_resource_get_user_data(buffer->resource);
+             tbm_bo_unmap((tbm_bo)(drm_buffer->driver_buffer));
+          }
+#endif
+
+        if (img)
+          evas_object_del(img);
+        if (ee)
+          ecore_evas_free(ee);
+     }
+
+   return reply;
+}
+
+static const Eldbus_Method methods[] = {
+   {
+      "get_window_info", NULL, ELDBUS_ARGS({"a(usiiiiibb)", "array of ec"}),
+      _e_info_server_cb_get_window_info, 0
+   },
+   {
+      "shot_topvwins", ELDBUS_ARGS({"s", "directory"}), NULL,
+      _e_info_server_cb_shot_topvwins, ELDBUS_METHOD_FLAG_NOREPLY
+   },
+   { NULL, NULL, NULL, NULL, 0 }
+};
+
+static const Eldbus_Service_Interface_Desc iface_desc = {
+     IFACE, methods, NULL, NULL, NULL, NULL
+};
+
+EINTERN int
+e_info_server_init(void)
+{
+   eldbus_init();
+
+   e_info_server.conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
+   EINA_SAFETY_ON_NULL_GOTO(e_info_server.conn, err);
+
+   e_info_server.iface = eldbus_service_interface_register(e_info_server.conn,
+                                                           PATH,
+                                                           &iface_desc);
+   EINA_SAFETY_ON_NULL_GOTO(e_info_server.iface, err);
+
+   return 1;
+err:
+   e_info_server_shutdown();
+   return 0;
+}
+
+EINTERN int
+e_info_server_shutdown(void)
+{
+   if (e_info_server.iface)
+     {
+        eldbus_service_interface_unregister(e_info_server.iface);
+        e_info_server.iface = NULL;
+     }
+   if (e_info_server.conn)
+     {
+        eldbus_connection_unref(e_info_server.conn);
+        e_info_server.conn = NULL;
+     }
+
+   eldbus_shutdown();
+
+   return 1;
+}
diff --git a/src/bin/e_info_server.h b/src/bin/e_info_server.h
new file mode 100644 (file)
index 0000000..9943d24
--- /dev/null
@@ -0,0 +1,10 @@
+#ifdef E_TYPEDEFS
+#else
+#ifndef E_INFO_SERVER_H
+#define E_INFO_SERVER_H
+
+EINTERN int e_info_server_init(void);
+EINTERN int e_info_server_shutdown(void);
+
+#endif
+#endif
index e789c81..ee4df0f 100644 (file)
@@ -1028,6 +1028,11 @@ main(int argc, char **argv)
    _e_main_shutdown_push(e_test_helper_shutdown);
    TS("E_Test_Helper Done");
 
+   TS("E_INFO_SERVER Init");
+   e_info_server_init();
+   _e_main_shutdown_push(e_info_server_shutdown);
+   TS("E_INFO_SERVER Done");
+
    if (e_config->show_splash)
      e_init_status_set(_("Setup Shelves"));
    TS("E_Shelf Init");