#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <glib.h>
#include <aul.h>
#include <aul_widget.h>
+#include <wayland-extension/tizen-remote-surface-client-protocol.h>
+#include <tbm_surface.h>
+#include <screen_connector_toolkit_evas.h>
+#include <Elementary.h>
#define MAX_BUFSZ 100
#define REGULAR_UID_MIN 5000
enum command_e {
CMD_LIST,
+ CMD_DUMP,
CMD_MAX,
};
enum option_e {
OPT_USER,
+ OPT_PATH,
OPT_MAX,
};
struct command_arg {
+ int argc;
+ char **argv;
uid_t uid;
+ char *path;
};
struct command {
void (*finish)(struct command_arg *);
};
+struct widget_info {
+ char *widget_id;
+ char *instance_id;
+ pid_t pid;
+ unsigned int surf;
+};
+
static gchar *help;
static gpointer cmd_opt[CMD_MAX];
static GOptionEntry cmd_entries[] = {
{ "list", 'l', 0, G_OPTION_ARG_NONE, &cmd_opt[CMD_LIST],
"Show running widget list", NULL },
+ { "dump", 'd', 0, G_OPTION_ARG_NONE, &cmd_opt[CMD_DUMP],
+ "Dump running widget windows", NULL },
{ NULL }
};
static gpointer opt[OPT_MAX];
static GOptionEntry opt_entries[] = {
{ "user", 'u', 0, G_OPTION_ARG_INT, &opt[OPT_USER],
"Specify the user ID", "USER ID" },
+ { "path", 'p', 0, G_OPTION_ARG_STRING, &opt[OPT_PATH],
+ "Specify the path", "PATH" },
{ NULL }
};
+static GList *widget_info_list;
+static Evas_Object *win;
static GOptionGroup *__get_opt_group(void)
{
{
struct command_arg cmd_arg = { 0, };
+ cmd_arg.argc = argc;
+ cmd_arg.argv = argv;
+
if (opt[OPT_USER])
cmd_arg.uid = GPOINTER_TO_INT(opt[OPT_USER]);
+ cmd_arg.path = opt[OPT_PATH];
+
return cmd_arg;
}
return r;
}
+static int __save_image(Evas_Object *image, const char *filename,
+ int quality, int compress)
+{
+ Ecore_Evas *ee;
+ Evas_Object *obj;
+ tbm_surface_h surface;
+ tbm_surface_info_s info;
+ Evas_Native_Surface *ns;
+ void *data;
+ int w;
+ int h;
+ char buf[128];
+
+ if (image == NULL || filename == NULL)
+ return -1;
+
+ snprintf(buf, sizeof(buf), "quality=%d compress=%d", quality, compress);
+ ns = evas_object_image_native_surface_get(image);
+ if (ns == NULL) {
+ evas_object_image_save(image, filename, NULL, buf);
+ return 0;
+ }
+
+ surface = (tbm_surface_h)ns->data.tbm.buffer;
+ if (surface == NULL)
+ return -1;
+
+ memset(&info, 0, sizeof(tbm_surface_info_s));
+ tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
+ data = info.planes[0].ptr;
+ w = info.planes[0].stride / 4;
+ h = info.height;
+
+ ee = ecore_evas_buffer_new(1, 1);
+ if (ee == NULL) {
+ tbm_surface_unmap(surface);
+ return -1;
+ }
+
+ obj = evas_object_image_add(ecore_evas_get(ee));
+ if (obj == NULL) {
+ ecore_evas_free(ee);
+ tbm_surface_unmap(surface);
+ return -1;
+ }
+
+ evas_object_image_alpha_set(obj, EINA_TRUE);
+ evas_object_image_size_set(obj, w, h);
+ evas_object_image_data_set(obj, data);
+
+ evas_object_image_save(obj, filename, NULL, buf);
+ tbm_surface_unmap(surface);
+ evas_object_del(obj);
+ ecore_evas_free(ee);
+
+ return 0;
+}
+
+static void __destroy_widget_info(struct widget_info *info)
+{
+ if (info == NULL)
+ return;
+
+ if (info->instance_id)
+ free(info->instance_id);
+ if (info->widget_id)
+ free(info->widget_id);
+ free(info);
+}
+
+static gint __compare_surf(gconstpointer a, gconstpointer b)
+{
+ struct widget_info *info = (struct widget_info *)a;
+ unsigned int surf = GPOINTER_TO_UINT(b);
+
+ if (info->surf == surf)
+ return 0;
+
+ return -1;
+}
+
+static void __screen_connector_toolkit_evas_added_cb(const char *appid,
+ const char *instance_id, int pid,
+ Evas_Object *image, void *data)
+{
+ const char *path = (const char *)data;
+ char cwd[PATH_MAX];
+ char buf[PATH_MAX];
+ unsigned int surf;
+ struct widget_info *info = NULL;
+ GList *found;
+
+ if (image == NULL)
+ return;
+
+ if (path == NULL)
+ path = getcwd(cwd, sizeof(cwd));
+ if (access(path, F_OK) != 0)
+ mkdir(path, 0755);
+
+ screen_connector_toolkit_evas_get_rid(image, (int *)&surf);
+ found = g_list_find_custom(widget_info_list, GUINT_TO_POINTER(surf),
+ __compare_surf);
+ if (found)
+ info = (struct widget_info *)found->data;
+
+ if (info == NULL) {
+ printf("Unknown surface(%u)", surf);
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "%s/%d_%s.jpg",
+ path, info->pid, info->instance_id);
+ __save_image(image, buf, 100, 100);
+
+ widget_info_list = g_list_remove(widget_info_list, info);
+ __destroy_widget_info(info);
+
+ if (widget_info_list == NULL)
+ elm_exit();
+}
+
+static void __screen_connector_toolkit_evas_removed_cb(const char *appid,
+ const char *instance_id, int pid,
+ Evas_Object *image, void *data)
+{
+ /* Nothing */
+}
+
+static void __screen_connector_toolkit_evas_updated_cb(const char *appid,
+ const char *instance_id, int pid,
+ Evas_Object *image, void *data)
+{
+ /* Nothing */
+}
+
+static void __get_widget_list(aul_widget_info_h info,
+ void *user_data)
+{
+ struct widget_info *w_info;
+ char *widget_id = NULL;
+ char *instance_id = NULL;
+ pid_t pid = -1;
+ unsigned int surf = 0;
+ int r;
+
+ if (info == NULL)
+ return;
+
+ r = aul_widget_info_get_widget_id(info, &widget_id);
+ if (r != AUL_R_OK)
+ return;
+
+ r = aul_widget_info_get_instance_id(info, &instance_id);
+ if (r != AUL_R_OK)
+ goto err;
+
+ r = aul_widget_info_get_pid(info, &pid);
+ if (r != AUL_R_OK)
+ goto err;
+
+ r = aul_widget_info_get_surface_id(info, &surf);
+ if (r != AUL_R_OK)
+ goto err;
+
+ w_info = calloc(1, sizeof(struct widget_info));
+ if (!w_info) {
+ printf("Failed to create widget info\n");
+ goto err;
+ }
+
+ w_info->widget_id = widget_id;
+ w_info->instance_id = instance_id;
+ w_info->pid = pid;
+ w_info->surf = surf;
+
+ widget_info_list = g_list_append(widget_info_list, w_info);
+
+ return;
+err:
+ if (instance_id);
+ free(instance_id);
+ if (widget_id)
+ free(widget_id);
+}
+
+static int __cmd_dump_init(struct command_arg *arg)
+{
+ int r;
+
+ r = aul_widget_info_foreach_for_uid(__get_widget_list,
+ NULL, arg->uid);
+ if (r < 0)
+ return -1;
+
+ if (widget_info_list == NULL) {
+ printf("Widget info is empty\n");
+ return -1;
+ }
+
+ elm_init(arg->argc, arg->argv);
+
+ win = elm_win_util_standard_add("widget-mgr", "widget-mgr");
+ if (!win) {
+ printf("Failed to add window\n");
+ elm_shutdown();
+ return -1;
+ }
+
+ elm_win_alpha_set(win, EINA_FALSE);
+ evas_object_show(win);
+
+ screen_connector_toolkit_evas_init(win,
+ SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET);
+
+ return 0;
+}
+
+static void __foreach_widget_info_list(gpointer data, gpointer user_data)
+{
+ struct widget_info *info = (struct widget_info *)data;
+ screen_connector_toolkit_evas_ops ops;
+ screen_connector_toolkit_evas_h handle;
+
+ if (info == NULL)
+ return;
+
+ ops.added_cb = __screen_connector_toolkit_evas_added_cb;
+ ops.removed_cb = __screen_connector_toolkit_evas_removed_cb;
+ ops.updated_cb = __screen_connector_toolkit_evas_updated_cb;
+
+ handle = screen_connector_toolkit_evas_add_by_rid(&ops, info->surf,
+ SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET, user_data);
+ if (handle == NULL) {
+ printf("Failed to add toolkit by rid(%u)", info->surf);
+ return;
+ }
+}
+
+static gboolean __dump_widgets(gpointer data)
+{
+ g_list_foreach(widget_info_list, __foreach_widget_info_list, data);
+
+ return G_SOURCE_REMOVE;
+}
+
+static int __cmd_dump_run(struct command_arg *arg)
+{
+ g_idle_add(__dump_widgets, arg->path);
+ elm_run();
+
+ return 0;
+}
+
+static void __cmd_dump_finish(struct command_arg *arg)
+{
+ screen_connector_toolkit_evas_fini(SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET);
+ evas_object_del(win);
+ elm_shutdown();
+}
+
static struct command cmd_table[] = {
[CMD_LIST] = {
.name = "list",
.run = __cmd_list_run,
.finish = NULL
},
+ [CMD_DUMP] = {
+ .name = "dump",
+ .init = __cmd_dump_init,
+ .run = __cmd_dump_run,
+ .finish = __cmd_dump_finish
+ },
};
static struct command *__find_command(void)