addd object dump features
authorSohyun Kim <anna1014.kim@samsung.com>
Thu, 26 Jul 2012 05:30:48 +0000 (14:30 +0900)
committerSohyun Kim <anna1014.kim@samsung.com>
Thu, 26 Jul 2012 06:31:50 +0000 (15:31 +0900)
config/mobile/base.src
configure.ac
packaging/elementary.spec
src/lib/Makefile.am
src/lib/elm_priv.h
src/lib/elm_win.c
src/modules/Makefile.am
src/modules/object_dump/Makefile.am [new file with mode: 0644]
src/modules/object_dump/object_dump.c [new file with mode: 0644]

index 5a4b129..d9a6c18 100644 (file)
@@ -31,7 +31,7 @@ group "Elm_Config" struct {
   value "finger_size" int: 60;
   value "fps" double: 6000.0;
   value "theme" string: "white-hd";
-  value "modules" string: "ctxpopup_copypasteUI>entry/api:datetime_input_ctxpopup>datetime/api";
+  value "modules" string: "ctxpopup_copypasteUI>entry/api:datetime_input_ctxpopup>datetime/api:object_dump>win/api";
   value "tooltip_delay" double: 1.0;
   value "cursor_engine_only" uchar: 1;
   value "focus_highlight_enable" uchar: 0;
index 7b10005..3055e7a 100644 (file)
@@ -305,6 +305,26 @@ if test "x$want_elementary_x" = "xyes" -a "x$have_elementary_x" = "xno"; then
     AC_MSG_ERROR([ecore-x support requested, but not found by pkg-config.])
 fi
 
+have_sdbd="no"
+want_sdb_enable="yes"
+AC_ARG_ENABLE([sdbd],
+        [AC_HELP_STRING([--disable-sdb], [disable sdbd support, @<:@default=detect@:>@])],
+        [want_sdb_enable=$enableval], [])
+
+if test "x$have_elementary_x" = "xyes" -a "x$want_sdb_enable" != "xno"; then
+   PKG_CHECK_MODULES([SDBD],
+      [ecore-ipc >= 1.0.999],
+      [
+       AC_DEFINE(SDB_ENABLE, 1, [sdb enable])
+       have_sdb="yes"
+       requirement_elm="ecore-ipc >= 1.0.999 ${requirement_elm}"
+      ],
+      [have_sdb="no"]
+   )
+else
+    have_sdb="no"
+fi
+
 have_elementary_fb="no"
 want_elementary_fb="auto"
 AC_ARG_ENABLE([ecore-fb],
@@ -717,6 +737,7 @@ src/modules/datetime_input_ctxpopup/Makefile
 src/modules/test_entry/Makefile
 src/modules/test_map/Makefile
 src/modules/ctxpopup_copypasteUI/Makefile
+src/modules/object_dump/Makefile
 src/edje_externals/Makefile
 src/examples/Makefile
 data/Makefile
index 783f9ca..06a8c13 100644 (file)
@@ -20,6 +20,7 @@ BuildRequires:  edje-devel
 BuildRequires:  edbus-devel
 BuildRequires:  efreet-devel
 BuildRequires:  ethumb-devel
+BuildRequires:  emotion-devel
 BuildRequires:  app-svc-devel
 BuildRequires:  libx11-devel
 
index 658fe36..1b4ff3b 100644 (file)
@@ -27,7 +27,8 @@ AM_CPPFLAGS = \
 @ELEMENTARY_ECORE_IMF_CFLAGS@ \
 @EVIL_CFLAGS@ \
 @EIO_CFLAGS@ \
-@EMOTION_CFLAGS@
+@EMOTION_CFLAGS@ \
+@SDBD_CFLAGS@
 
 if ELEMENTARY_WINDOWS_BUILD
 AM_CPPFLAGS += -DELEMENTARY_BUILD
index adefb32..22c0b9a 100644 (file)
@@ -6,6 +6,9 @@
 #ifdef HAVE_ELEMENTARY_X
 #include <Ecore_X.h>
 #endif
+#ifdef SDB_ENABLE
+#include <Ecore_Ipc.h>
+#endif
 #ifdef HAVE_ELEMENTARY_FB
 #include <Ecore_Fb.h>
 #endif
index 5460b2d..c52ec07 100644 (file)
@@ -3,6 +3,19 @@
 
 typedef struct _Elm_Win Elm_Win;
 
+#ifdef SDB_ENABLE
+typedef struct _Object_Dump_Mod Object_Dump_Mod;
+
+struct _Object_Dump_Mod
+{
+   Eina_List *(*tree_create) (Evas_Object *root);
+   void (*tree_free) (Eina_List *tree);
+   char *(*tree_string_get) (Eina_List *tree);
+   char *(*tree_string_get_for_sdb) (Eina_List *tree);
+   char *(*command_for_sdb) (Eina_List *tree, char *data);
+};
+#endif
+
 struct _Elm_Win
 {
    Ecore_Evas *ee;
@@ -13,6 +26,11 @@ struct _Elm_Win
    Ecore_X_Window xwin;
    Ecore_Event_Handler *client_message_handler;
 #endif
+#ifdef SDB_ENABLE
+   Object_Dump_Mod *od_mod;
+   Ecore_Ipc_Server *sdb_server;
+   Ecore_Event_Handler *sdb_server_data_handler, *sdb_server_del_handler;
+#endif
    Ecore_Job *deferred_resize_job;
    Ecore_Job *deferred_child_eval_job;
 
@@ -428,6 +446,20 @@ _elm_win_focus_out(Ecore_Evas *ee)
      {
         /* do nothing */
      }
+#ifdef SDB_ENABLE
+   if (win->sdb_server)
+     {
+        if (win->od_mod) free(win->od_mod);
+        ecore_event_handler_del(win->sdb_server_data_handler);
+        ecore_event_handler_del(win->sdb_server_del_handler);
+        ecore_ipc_shutdown();
+
+        win->od_mod = NULL;
+        win->sdb_server = NULL;
+        win->sdb_server_data_handler = NULL;
+        win->sdb_server_del_handler = NULL;
+     }
+#endif
 }
 
 static void
@@ -763,6 +795,20 @@ _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_inf
    if (win->client_message_handler)
      ecore_event_handler_del(win->client_message_handler);
 #endif
+#ifdef SDB_ENABLE
+   if (win->sdb_server)
+     {
+        if (win->od_mod) free(win->od_mod);
+        ecore_event_handler_del(win->sdb_server_data_handler);
+        ecore_event_handler_del(win->sdb_server_del_handler);
+        ecore_ipc_shutdown();
+
+        win->od_mod = NULL;
+        win->sdb_server = NULL;
+        win->sdb_server_data_handler = NULL;
+        win->sdb_server_del_handler = NULL;
+     }
+#endif
    // FIXME: Why are we flushing edje on every window destroy ??
    //   edje_file_cache_flush();
    //   edje_collection_cache_flush();
@@ -1249,6 +1295,101 @@ _elm_win_translate(void)
       elm_widget_translate(obj);
 }
 
+#ifdef SDB_ENABLE
+static int
+_elm_win_send_message_to_sdb(Elm_Win *win, char *msg)
+{
+   if (win->sdb_server && msg)
+     return ecore_ipc_server_send(win->sdb_server, 0, 0, 0, 0, 0, msg, strlen(msg)+1);
+
+   return 0;
+}
+
+static Eina_Bool
+_elm_win_sdb_server_sent(void *data, int type __UNUSED__, void *event)
+{
+   Elm_Win *win = data;
+   Ecore_Ipc_Event_Server_Data *e;
+   e = (Ecore_Ipc_Event_Server_Data *) event;
+
+   if (win->sdb_server != e->server) return EINA_FALSE;
+   if (!win->od_mod) return EINA_FALSE;
+
+   Object_Dump_Mod *mod = win->od_mod;
+   char *msg = strdup((char *)e->data);
+   const char *command = strtok(msg,"=");
+   char *text = NULL;
+   Eina_List *tree = NULL;
+
+   if (mod->tree_create)
+      tree = mod->tree_create(win->win_obj);
+
+   if (tree)
+     {
+        if (!strcmp(command, "AT+DUMPWND"))
+          {
+             if (mod->tree_string_get_for_sdb)
+                text = mod->tree_string_get_for_sdb(tree);
+          }
+        else if (!strcmp(command, "AT+GETPARAM") ||
+                 !strcmp(command, "AT+GETOTEXT") ||
+                 !strcmp(command, "AT+CLRENTRY") ||
+                 !strcmp(command, "AT+SETENTRY"))
+          {
+             if (mod->command_for_sdb)
+                text = mod->command_for_sdb(tree, e->data);
+          }
+        else
+           text = strdup("Invaild Command!!");
+
+        _elm_win_send_message_to_sdb(win, text);
+        if (mod->tree_free) mod->tree_free(tree);
+        if (text) free(text);
+     }
+   else
+      return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_elm_win_sdb_server_del(void *data, int type __UNUSED__, void *event __UNUSED__)
+{
+   Elm_Win *win = data;
+
+   if (win->od_mod) free(win->od_mod);
+   ecore_event_handler_del(win->sdb_server_data_handler);
+   ecore_event_handler_del(win->sdb_server_del_handler);
+   ecore_ipc_shutdown();
+
+   win->od_mod = NULL;
+   win->sdb_server = NULL;
+   win->sdb_server_data_handler = NULL;
+   win->sdb_server_del_handler = NULL;
+
+   return EINA_TRUE;
+}
+
+static Object_Dump_Mod *
+_object_dump_mod_init()
+{
+   Elm_Module *mod = NULL;
+   mod = _elm_module_find_as("win/api");
+   if (!mod) return NULL;
+
+   mod->api = malloc(sizeof(Object_Dump_Mod));
+   if (!mod->api) return NULL;
+
+   ((Object_Dump_Mod *)(mod->api))->tree_create = _elm_module_symbol_get(mod, "tree_create");
+   ((Object_Dump_Mod *)(mod->api))->tree_free = _elm_module_symbol_get(mod, "tree_free");
+   ((Object_Dump_Mod *)(mod->api))->tree_string_get = _elm_module_symbol_get(mod, "tree_string_get");
+   ((Object_Dump_Mod *)(mod->api))->tree_string_get_for_sdb = _elm_module_symbol_get(mod, "tree_string_get_for_sdb");
+   ((Object_Dump_Mod *)(mod->api))->command_for_sdb = _elm_module_symbol_get(mod, "command_for_sdb");
+
+   return mod->api;
+}
+#endif
+
 #ifdef HAVE_ELEMENTARY_X
 static Eina_Bool
 _elm_win_client_message(void *data, int type __UNUSED__, void *event)
@@ -1286,6 +1427,35 @@ _elm_win_client_message(void *data, int type __UNUSED__, void *event)
                }
           }
      }
+#ifdef SDB_ENABLE
+   else if (e->message_type == ECORE_X_ATOM_SDB_SERVER_CONNECT)
+     {
+        if ((unsigned)e->data.l[0] == win->xwin)
+          {
+             ecore_ipc_init();
+             win->od_mod = _object_dump_mod_init();
+
+             win->sdb_server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, "sdb", 0, NULL);
+             win->sdb_server_data_handler = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _elm_win_sdb_server_sent, win);
+             win->sdb_server_del_handler = ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _elm_win_sdb_server_del, win);
+          }
+     }
+   else if (e->message_type == ECORE_X_ATOM_SDB_SERVER_DISCONNECT)
+     {
+        if ((unsigned)e->data.l[0] == win->xwin)
+          {
+             if (win->od_mod) free(win->od_mod);
+             ecore_event_handler_del(win->sdb_server_data_handler);
+             ecore_event_handler_del(win->sdb_server_del_handler);
+             ecore_ipc_shutdown();
+
+             win->od_mod = NULL;
+             win->sdb_server = NULL;
+             win->sdb_server_data_handler = NULL;
+             win->sdb_server_del_handler = NULL;
+          }
+     }
+#endif
    return ECORE_CALLBACK_PASS_ON;
 }
 #endif
index fbbbae9..424372c 100644 (file)
@@ -6,4 +6,5 @@ test_entry \
 ctxpopup_copypasteUI \
 test_map \
 access_output \
-datetime_input_ctxpopup
+datetime_input_ctxpopup \
+object_dump
diff --git a/src/modules/object_dump/Makefile.am b/src/modules/object_dump/Makefile.am
new file mode 100644 (file)
index 0000000..903b38e
--- /dev/null
@@ -0,0 +1,33 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-DELM_INTERNAL_API_ARGESFSDFEFC=1 \
+-I. \
+-I$(top_builddir) \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/lib \
+-I$(top_builddir)/src/lib \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+@ELEMENTARY_CFLAGS@ \
+@ELEMENTARY_X_CFLAGS@ \
+@ELEMENTARY_FB_CFLAGS@ \
+@ELEMENTARY_WIN32_CFLAGS@ \
+@ELEMENTARY_WINCE_CFLAGS@ \
+@ELEMENTARY_EDBUS_CFLAGS@ \
+@ELEMENTARY_EFREET_CFLAGS@ \
+@ELEMENTARY_ETHUMB_CFLAGS@
+
+if ELEMENTARY_WINDOWS_BUILD
+AM_CPPFLAGS += -DELEMENTARY_BUILD
+endif
+
+pkgdir = $(libdir)/elementary/modules/object_dump/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = object_dump.c
+
+module_la_LIBADD = @ELEMENTARY_LIBS@ $(top_builddir)/src/lib/libelementary.la
+module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/src/modules/object_dump/object_dump.c b/src/modules/object_dump/object_dump.c
new file mode 100644 (file)
index 0000000..89a7108
--- /dev/null
@@ -0,0 +1,503 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+#include <sys/time.h>
+
+typedef struct _Dump_Tree_Item Dump_Tree_Item;
+
+struct _Dump_Tree_Item
+{
+   const char *type;
+   const char *elm_type;
+   void *ptr;
+   const char *text;
+   int x, y, w, h;
+   Eina_Bool visible;
+   Eina_List *children;
+   struct _Dump_Tree_Item *parent;
+};
+
+static void
+_add_tree_items(Evas_Object *obj, Dump_Tree_Item *parent)
+{
+   Dump_Tree_Item *item;
+   Eina_List *children;
+   Evas_Object *child;
+
+   item = calloc(1, sizeof(Dump_Tree_Item));
+   if(!item) return;
+
+   item->type = eina_stringshare_add(evas_object_type_get(obj));
+   if (!strcmp(item->type, "elm_widget"))
+      item->elm_type = eina_stringshare_add(elm_object_widget_type_get(obj));
+   item->ptr = obj;
+   evas_object_geometry_get(obj, &item->x, &item->y, &item->w, &item->h);
+   item->visible = evas_object_visible_get(obj);
+   if (!strcmp(item->type, "text"))
+      item->text = eina_stringshare_add(evas_object_text_text_get(obj));
+   else if (!strcmp(item->type, "textblock"))
+     {
+        const char *str;
+        str = evas_object_textblock_text_markup_get(obj);
+        item->text = eina_stringshare_add(evas_textblock_text_markup_to_utf8(obj, str));
+     }
+
+   item->parent = parent;
+   parent->children = eina_list_append(parent->children, item);
+
+   children = evas_object_smart_members_get(obj);
+   EINA_LIST_FREE(children, child)
+      _add_tree_items(child, item);
+}
+
+static void
+_add_item_string(Eina_List *children, Eina_Strbuf *buf, int depth)
+{
+   Eina_List *l;
+   Dump_Tree_Item *item;
+   int i;
+
+   EINA_LIST_FOREACH(children, l, item)
+     {
+        for (i = 0; i < depth; i++)
+           eina_strbuf_append(buf, " ");
+
+        if (item->elm_type) eina_strbuf_append_printf(buf, "[%s,", item->elm_type);
+        else eina_strbuf_append_printf(buf, "[%s,", item->type);
+        eina_strbuf_append_printf(buf, "%p,", item->ptr);
+        if (item->text) eina_strbuf_append_printf(buf, "\"%s\",", item->text);
+        eina_strbuf_append_printf(buf, "%d,%d,%d,%d,%d {", item->x, item->y, item->w, item->h, item->visible);
+
+        if (item->children)
+          {
+             eina_strbuf_append(buf, "\n");
+             _add_item_string(item->children, buf, depth + 1);
+
+             for (i = 0; i < depth; i++)
+                eina_strbuf_append(buf, " ");
+          }
+        eina_strbuf_append(buf, "}]\n");
+     }
+}
+
+static char *
+_get_text(Dump_Tree_Item *item)
+{
+   Dump_Tree_Item *child;
+   Eina_List *children = NULL, *l;
+   Eina_Strbuf *strbuf = NULL;
+
+   // if it is an elm_widget,
+   if (item->elm_type && item->children)
+     {
+        child = eina_list_data_get(item->children);
+        if (!strcmp(child->type, "edje"))
+           children = child->children;
+     }
+   // if it is an edje object,
+   else if (!strcmp(item->type, "edje"))
+      children = item->children;
+
+   EINA_LIST_FOREACH(children, l, child)
+     {
+        if (!strcmp(child->type, "text") || !strcmp(child->type, "textblock"))
+          {
+             if (child->text && strlen(child->text))
+               {
+                  if (!strbuf) strbuf = eina_strbuf_new();
+                  else eina_strbuf_append(strbuf, ",");
+                  eina_strbuf_append_printf(strbuf, "\"%s\"", child->text);
+               }
+          }
+     }
+
+   if (strbuf) return eina_strbuf_string_steal(strbuf);
+   return NULL;
+}
+
+static Eina_Bool
+_item_can_be_added(Dump_Tree_Item *item)
+{
+   Dump_Tree_Item *parent, *child;
+   Eina_List *l;
+
+   if (item->elm_type)
+      return EINA_TRUE;
+   else if (!strcmp(item->type, "edje"))
+     {
+        // widget layout
+        parent = item->parent;
+        if (parent->elm_type &&
+            item->x == parent->x && item->y == parent->y &&
+            item->w == parent->w && item->h == parent->h)
+           return EINA_FALSE;
+
+        // if the edje has valid child objects
+        EINA_LIST_FOREACH(item->children, l, child)
+          {
+             if (child->elm_type)
+                return EINA_TRUE;
+             else if (!strcmp(child->type, "text") || !strcmp(child->type, "textblock"))
+               {
+                  if (child->text && strlen(child->text))
+                     return EINA_TRUE;
+               }
+          }
+     }
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_add_item_string_for_sdb(Eina_List *children, Eina_Strbuf *buf, int depth)
+{
+   Eina_List *l;
+   Dump_Tree_Item *item;
+   Eina_Bool ret, item_add = EINA_FALSE, children_added = EINA_FALSE;
+   char *str;
+   int i;
+
+   EINA_LIST_FOREACH(children, l, item)
+     {
+        item_add = _item_can_be_added(item);
+
+        /* add item info */
+        if (item_add)
+          {
+             if (depth)
+               {
+                  eina_strbuf_append(buf, "\n");
+                  for (i = 0; i < depth; i++)
+                     eina_strbuf_append(buf, " ");
+               }
+
+             if (item->elm_type) eina_strbuf_append_printf(buf, "[%s,", item->elm_type);
+             else eina_strbuf_append_printf(buf, "[%s,", item->type);
+             eina_strbuf_append_printf(buf, "%p,", item->ptr);
+             str = _get_text(item);
+             if (str)
+               {
+                  eina_strbuf_append_printf(buf, "%s,", str);
+                  free(str);
+               }
+             else eina_strbuf_append(buf, "\"\",");
+             eina_strbuf_append_printf(buf, "%d,%d,%d,%d,%d {", item->x, item->y, item->w, item->h, item->visible);
+          }
+
+        /* call child node */
+        if (item->children)
+          {
+             if (item_add)
+                ret = _add_item_string_for_sdb(item->children, buf, depth + 1);
+             else
+                ret = _add_item_string_for_sdb(item->children, buf, depth);
+          }
+
+        /* close the item info */
+        if (item_add && ret) //if it has children
+          {
+             eina_strbuf_append(buf, "\n");
+             for (i = 0; i < depth; i++)
+                eina_strbuf_append(buf, " ");
+             eina_strbuf_append(buf, "}]");
+          }
+        else if(item_add)
+          eina_strbuf_append(buf, "}]");
+
+        children_added |= item_add;
+        children_added |= ret;
+
+        str = NULL;
+        item_add = EINA_FALSE;
+        ret = EINA_FALSE;
+     }
+
+   return children_added;
+}
+
+static Dump_Tree_Item *
+_get_item_info(Eina_List *tree, char *id)
+{
+   Eina_List *l;
+   Dump_Tree_Item *item, *child;
+   const char *str;
+
+   EINA_LIST_FOREACH(tree, l, item)
+     {
+        str = eina_stringshare_printf("%p", item->ptr);
+        if (!strcmp(str, id))
+          {
+             eina_stringshare_del(str);
+             return item;
+          }
+
+        if (item->children)
+          {
+             child = _get_item_info(item->children, id);
+             if (child) return child;
+          }
+     }
+     return NULL;
+}
+
+/**
+ * Create a object dump tree
+ * It creates the tree from the evas of the root object
+ *
+ * @param root The root object
+ * @return The list of Dump_Tree_Item
+ */
+EAPI Eina_List *
+tree_create(Evas_Object *root)
+{
+   Evas *e;
+   Eina_List *tree = NULL;
+   Dump_Tree_Item *item;
+   Eina_List *objs, *l;
+   Evas_Object *obj;
+
+   /* root node */
+   item = calloc(1, sizeof(Dump_Tree_Item));
+   if (!item) return NULL;
+
+   item->type = eina_stringshare_add(evas_object_type_get(root));
+   if (!strcmp(item->type, "elm_widget"))
+      item->elm_type = eina_stringshare_add(elm_object_widget_type_get(root));
+   item->ptr = root;
+   evas_object_geometry_get(root, &item->x, &item->y, &item->w, &item->h);
+   item->visible = evas_object_visible_get(root);
+
+   tree = eina_list_append(tree, item);
+
+   /* children node*/
+   e = evas_object_evas_get(root);
+   objs = evas_objects_in_rectangle_get(e, item->x, item->y, item->w, item->h, EINA_TRUE, EINA_FALSE);
+
+   // remove root object from the list
+   EINA_LIST_FOREACH(objs, l, obj)
+     {
+        if (obj == root)
+          {
+             objs = eina_list_remove_list(objs, l);
+             break;
+          }
+     }
+
+   //FIXME: other object except for elm_win
+   EINA_LIST_FREE(objs, obj)
+      _add_tree_items(obj, item);
+
+   return tree;
+}
+
+/**
+ * Free the object dump tree
+ *
+ * @param tree The object dump tree
+ */
+EAPI void
+tree_free(Eina_List *tree)
+{
+   Dump_Tree_Item *item;
+   if (!tree) return;
+
+   EINA_LIST_FREE(tree, item)
+     {
+        if (item->type) eina_stringshare_del(item->type);
+        if (item->elm_type) eina_stringshare_del(item->elm_type);
+        if (item->text) eina_stringshare_del(item->text);
+        if (item->children)
+           tree_free(item->children);
+     }
+}
+
+/**
+ * Get a string of the tree items
+ *
+ * @param tree The object dump tree
+ * @return The tree string (it should be freed)
+ */
+EAPI char *
+tree_string_get(Eina_List *tree)
+{
+   Eina_Strbuf *buf = NULL;
+   if (!tree) return NULL;
+
+   buf = eina_strbuf_new();
+   if (!buf) return NULL;
+
+   eina_strbuf_append(buf, "[object,address,(text),x,y,w,h,visible]\n");
+   _add_item_string(tree, buf, 0);
+
+   return eina_strbuf_string_steal(buf);
+}
+
+/**
+ * Get a string of the tree items for sdb
+ *
+ * @param tree The object dump tree
+ * @return The tree string (it should be freed)
+ */
+EAPI char *
+tree_string_get_for_sdb(Eina_List *tree)
+{
+   Eina_Strbuf *buf = NULL;
+   if (!tree) return NULL;
+
+   buf = eina_strbuf_new();
+   if (!buf) return NULL;
+
+   eina_strbuf_append(buf, "+DUMPWND:");
+   _add_item_string_for_sdb(tree, buf, 0);
+
+   return eina_strbuf_string_steal(buf);
+}
+
+/**
+ * Get a string for the command from sdb server
+ *
+ * @param tree The object dump tree
+ * @param data Command from the sdb server
+ * @return The tree string (it should be freed)
+ */
+EAPI char *
+command_for_sdb(Eina_List *tree, char *data)
+{
+   char *str = NULL;
+   char *command, *id, *text, *result;
+   Dump_Tree_Item *item = NULL;
+   Eina_Strbuf *buf = NULL;
+
+   if (!tree) return NULL;
+
+   // get command, arguments
+   str = strdup(data);
+   if (!str) return NULL;
+
+   command = strtok(str + 2, "=");
+   id = strtok(NULL, ",");
+   text = strtok(NULL, ",");
+
+   item = _get_item_info(tree, id);
+   if (!item)
+     {
+        free(str);
+        return strdup("Invalid Item!!");
+     }
+
+   // response for the command
+   buf = eina_strbuf_new();
+   if (!buf) return NULL;
+
+   eina_strbuf_append_printf(buf, "%s:", command);
+
+   if (!strcmp(command, "+GETOTEXT"))
+     {
+        result = _get_text(item);
+        if (result)
+          {
+             eina_strbuf_append_printf(buf, "%s,", result);
+             free(result);
+          }
+     }
+   else if (!strcmp(command, "+SETENTRY"))
+     {
+        if (!strcmp(item->elm_type, "entry"))
+          {
+             elm_object_text_set(item->ptr, text);
+             eina_strbuf_append_printf(buf, "OK");
+          }
+     }
+   else if (!strcmp(command, "+CLRENTRY"))
+     {
+        if (!strcmp(item->elm_type, "entry"))
+          {
+             elm_object_text_set(item->ptr, "");
+             eina_strbuf_append_printf(buf, "OK");
+          }
+     }
+   else if (!strcmp(command, "+GETPARAM"))
+     {
+        // common data
+        if (item->elm_type) eina_strbuf_append_printf(buf, "%s,", item->elm_type);
+        else eina_strbuf_append_printf(buf, "%s,", item->type);
+        eina_strbuf_append_printf(buf, "%p,", item->ptr);
+        eina_strbuf_append_printf(buf, "%d,%d,%d,%d,%d,", item->x, item->y, item->w, item->h, item->visible);
+
+        // widget specific data
+        if (!strcmp(item->elm_type, "button"))
+          {
+             result = elm_object_text_get(item->ptr);
+             if (result) eina_strbuf_append_printf(buf, "\"%s\"", result);
+             else eina_strbuf_append(buf, "\"\"");
+          }
+        else if (!strcmp(item->elm_type, "check"))
+          {
+             result = elm_object_text_get(item->ptr);
+             if (result) eina_strbuf_append_printf(buf, "\"%s\",%d", result, elm_check_state_get(item->ptr));
+             else eina_strbuf_append_printf(buf, "\"\",%d", elm_check_state_get(item->ptr));
+          }
+        else if (!strcmp(item->elm_type, "radio"))
+          {
+             result = elm_object_text_get(item->ptr);
+             if (result) eina_strbuf_append_printf(buf, "\"%s\",%d", result, elm_radio_state_value_get(item->ptr));
+             else eina_strbuf_append_printf(buf, "\"\",%d", elm_radio_state_value_get(item->ptr));
+          }
+        else if (!strcmp(item->elm_type, "naviframe"))
+          {
+             result = elm_object_item_text_get(elm_naviframe_top_item_get(item->ptr));
+             if (result) eina_strbuf_append_printf(buf, "\"%s\"", result);
+             else eina_strbuf_append_printf(buf, "\"\"");
+          }
+        else if (!strcmp(item->elm_type, "popup"))
+          {
+             result = elm_object_part_text_get(item->ptr, "title,text");
+             if (result) eina_strbuf_append_printf(buf, "\"%s\"", result);
+             else eina_strbuf_append(buf, "\"\"");
+          }
+        else if (!strcmp(item->elm_type, "calendar"))
+          {
+             struct tm stime;
+             elm_calendar_selected_time_get(item->ptr, &stime);
+             eina_strbuf_append_printf(buf, "%d-%d-%d", stime.tm_year + 1900, stime.tm_mon + 1, stime.tm_mday);
+          }
+        else if (!strcmp(item->elm_type, "datetime"))
+          {
+             struct tm stime;
+             elm_datetime_value_get(item->ptr, &stime);
+             eina_strbuf_append_printf(buf, "%d-%d-%d %d:%d", stime.tm_year + 1900, stime.tm_mon + 1, stime.tm_mday, stime.tm_hour, stime.tm_min);
+          }
+        else if (!strcmp(item->elm_type, "label"))
+          {
+             const char *markup;
+             markup = elm_object_text_get(item->ptr);
+             result = evas_textblock_text_markup_to_utf8(NULL, markup);
+             if (result) eina_strbuf_append_printf(buf, "\"%s\"", result);
+             else eina_strbuf_append(buf, "\"\"");
+          }
+        else if (!strcmp(item->elm_type, "entry"))
+          {
+             Ecore_IMF_Context *context = elm_entry_imf_context_get(item->ptr);
+             const char *markup = elm_object_text_get(item->ptr);
+             result = evas_textblock_text_markup_to_utf8(NULL, markup);
+             if (result) eina_strbuf_append_printf(buf, "\"%s\",%d", result, ecore_imf_context_input_panel_state_get(context));
+             else eina_strbuf_append_printf(buf, "\"\",%d", ecore_imf_context_input_panel_state_get(context));
+          }
+     }
+
+   free(str);
+
+   return eina_strbuf_string_steal(buf);
+}
+
+// module api funcs needed
+EAPI int
+elm_modapi_init(void *m __UNUSED__)
+{
+   return 1; // succeed always
+}
+
+EAPI int
+elm_modapi_shutdown(void *m __UNUSED__)
+{
+   return 1; // succeed always
+}