zehortigoza pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=230c484f3f3eda8b20f365af31ebc6984359b046

commit 230c484f3f3eda8b20f365af31ebc6984359b046
Author: José Roberto de Souza <jose.so...@intel.com>
Date:   Fri Sep 6 15:39:37 2013 -0300

    Implementation of elm_app_server
    
    This is disabled by default, and enabled in settings.
    Also there a option to automatic restore opened terminals.
---
 configure.ac               |   3 +
 m4/efl_beta.m4             |   5 +
 m4/efl_eo.m4               |   6 +
 src/bin/Makefile.am        |   4 +-
 src/bin/app_server.c       | 408 +++++++++++++++++++++++++++++++++++++++++++++
 src/bin/app_server.h       |   8 +
 src/bin/app_server_eet.c   | 255 ++++++++++++++++++++++++++++
 src/bin/app_server_eet.h   |  41 +++++
 src/bin/config.c           |  11 ++
 src/bin/config.h           |   2 +
 src/bin/main.c             |  11 +-
 src/bin/options_behavior.c |  72 ++++++++
 src/bin/win.c              |   5 +
 13 files changed, 829 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index cc2c80b..13b259a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,9 @@ requirements="\
    ethumb_client >= 1.7.0 \
    "
 
+EFL_ENABLE_EO_API_SUPPORT
+EFL_ENABLE_BETA_API_SUPPORT
+
 PKG_CHECK_MODULES([TERMINOLOGY], [${requirements}])
 
 PKG_CHECK_MODULES([ELDBUS],
diff --git a/m4/efl_beta.m4 b/m4/efl_beta.m4
new file mode 100644
index 0000000..c804729
--- /dev/null
+++ b/m4/efl_beta.m4
@@ -0,0 +1,5 @@
+dnl use: EFL_ENABLE_BETA_API_SUPPORT
+AC_DEFUN([EFL_ENABLE_BETA_API_SUPPORT],
+[
+  AC_DEFINE([EFL_BETA_API_SUPPORT], [1], [Enable access to unstable EFL API 
that are still in beta])
+])
diff --git a/m4/efl_eo.m4 b/m4/efl_eo.m4
new file mode 100644
index 0000000..864baf5
--- /dev/null
+++ b/m4/efl_eo.m4
@@ -0,0 +1,6 @@
+dnl use: EFL_ENABLE_EO_API_SUPPORT
+AC_DEFUN([EFL_ENABLE_EO_API_SUPPORT],
+[
+  AC_DEFINE([EFL_EO_API_SUPPORT], [1], [Enable access to unstable EFL Eo API])
+])
+
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index e95dae7..b18e440 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -42,7 +42,9 @@ utf8.c utf8.h \
 win.c win.h \
 utils.c utils.h \
 dbus.c dbus.h \
-extns.h
+extns.h \
+app_server.c app_server.h \
+app_server_eet.c app_server_eet.h
 
 tybg_SOURCES = \
 tybg.c
diff --git a/src/bin/app_server.c b/src/bin/app_server.c
new file mode 100644
index 0000000..d96b08b
--- /dev/null
+++ b/src/bin/app_server.c
@@ -0,0 +1,408 @@
+#include "private.h"
+
+#include <Elementary.h>
+
+#include "main.h"
+#include "termio.h"
+#include "app_server_eet.h"
+
+static Elm_App_Server *server = NULL;
+static Eina_Bool _ignore_term_add = EINA_FALSE;
+static Terminology_Item *views_eet = NULL;
+
+static void
+_user_config_file_path_build(char *dir, unsigned int size, const char *id)
+{
+   const char *home = getenv("HOME");
+
+   if (!home)
+     home = "";
+
+   snprintf(dir, size, "%s/.terminology/", home);
+   if (!ecore_file_is_dir(dir))
+     ecore_file_mkpath(dir);
+
+   snprintf(dir, size, "%s/.terminology/%s", home, id);
+}
+
+void
+app_server_term_del(Evas_Object *term)
+{
+   Elm_App_Server_View *view;
+   const char *id;
+
+   view = evas_object_data_del(term, "app_view");
+   if (!view)
+     return;
+
+   eo_do(view, elm_app_server_view_id_get(&id));
+   terminology_item_term_entries_del(views_eet, id);
+
+   eo_del(view);
+}
+
+static Eina_Bool
+_view_closed_cb(void *data, Eo *view,
+                const Eo_Event_Description *desc EINA_UNUSED,
+                void *event_info EINA_UNUSED)
+{
+   Term *term = data;
+   const char *id;
+   char eet_dir[PATH_MAX];
+
+   if (term)
+     {
+        Evas_Object *term_object;
+
+        term_object = main_term_evas_object_get(term);
+        evas_object_data_del(term_object, "app_view");
+        main_close(main_win_evas_object_get(main_term_win_get(term)),
+                   term_object);
+     }
+
+   eo_do(view, elm_app_server_view_id_get(&id));
+   terminology_item_term_entries_del(views_eet, id);
+
+   eo_del(view);
+   return EINA_TRUE;
+}
+
+static void
+_term_title_changed_cb(void *data, Evas_Object *obj,
+                       void *event_info EINA_UNUSED)
+{
+   const char *title = termio_title_get(obj);
+   eo_do(data, elm_app_server_view_title_set(title));
+}
+
+static void
+_term_icon_changed_cb(void *data, Evas_Object *obj,
+                      void *event_info EINA_UNUSED)
+{
+   const char *icon = termio_icon_name_get(obj);
+   eo_do(data, elm_app_server_view_icon_set(icon));
+}
+
+static Eina_Bool
+_view_save_cb(void *data, Eo *view,
+              const Eo_Event_Description *desc EINA_UNUSED,
+              void *event_info EINA_UNUSED)
+{
+   Term *term = data;
+   char dir[PATH_MAX];
+   Evas_Object *term_object;
+   const char *id;
+   Term_Item *term_eet;
+
+   term_object = main_term_evas_object_get(data);
+
+   /*
+    * if we call elm_app_server_save() in some case that the terminology
+    * will continue run, this data_del will lead to issues.
+    */
+   evas_object_data_del(term_object, "app_view");
+
+   termio_cwd_get(term_object, dir, sizeof(dir));
+   eo_do(view, elm_app_server_view_id_get(&id));
+
+   term_eet = terminology_item_term_entries_get(views_eet, id);
+   if (term_eet)
+     {
+        term_item_dir_set(term_eet, dir);
+        return EINA_TRUE;
+     }
+
+   term_eet = term_item_new(id, dir);
+   terminology_item_term_entries_add(views_eet, id, term_eet);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_view_resumed_cb(void *data, Eo *view,
+                 const Eo_Event_Description *desc EINA_UNUSED,
+                 void *event_info EINA_UNUSED)
+{
+   Term *term = data;
+   Win *wn;
+   Eina_List **wins;
+   const char *title, *id;
+   Evas_Object *term_object;
+   const char *dir = NULL;
+   Term_Item *term_eet;
+
+   if (term)
+     {
+        main_term_focus(term);
+        return EINA_TRUE;
+     }
+
+   eo_do(server, eo_base_data_get("wins", (void **)&wins));
+   wn = eina_list_data_get(*wins);
+   if (!wn)
+     {
+        ERR("There is no window open");
+        return EINA_TRUE;
+     }
+
+   term = eina_list_data_get(main_win_terms_get(wn));
+
+   eo_do(view, elm_app_server_view_id_get(&id));
+   term_eet = terminology_item_term_entries_get(views_eet, id);
+   if (term_eet)
+     {
+        dir = term_item_dir_get(term_eet);
+        //not valid data saved
+        if (!dir || dir[0] != '/')
+          {
+             terminology_item_term_entries_del(views_eet, id);
+             dir = NULL;
+          }
+     }
+
+   _ignore_term_add = EINA_TRUE;
+   if (dir)
+     main_new_with_dir(main_win_evas_object_get(wn),
+                        main_term_evas_object_get(term), dir);
+   else
+     main_new(main_win_evas_object_get(wn), main_term_evas_object_get(term));
+   _ignore_term_add = EINA_FALSE;
+
+   //just add term
+   term = eina_list_last_data_get(main_win_terms_get(wn));
+   term_object = main_term_evas_object_get(term);
+   title = termio_title_get(term_object);
+
+   evas_object_data_set(term_object, "app_view", view);
+
+   eo_do(view, elm_app_server_view_title_set(title),
+         elm_app_server_view_window_set(
+                  main_win_evas_object_get(main_term_win_get(term))),
+         eo_event_callback_del(ELM_APP_SERVER_VIEW_EV_CLOSED, _view_closed_cb,
+                               NULL),
+         eo_event_callback_del(ELM_APP_SERVER_VIEW_EV_RESUMED, 
_view_resumed_cb,
+                               NULL),
+         eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_CLOSED, _view_closed_cb,
+                               term),
+         eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_RESUMED, 
_view_resumed_cb,
+                               term),
+         eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_SAVE, _view_save_cb,
+                               term));
+
+   evas_object_smart_callback_add(term_object, "title,change",
+                                  _term_title_changed_cb, view);
+   evas_object_smart_callback_add(term_object, "icon,change",
+                                  _term_icon_changed_cb, term);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_server_terminate_cb(void *data, Eo *obj,
+                     const Eo_Event_Description *desc EINA_UNUSED,
+                     void *event_info EINA_UNUSED)
+{
+   Eina_List **wins = data, *l, *l2;
+   Win *wn;
+
+   EINA_LIST_FOREACH_SAFE(*wins, l, l2, wn)
+     evas_object_del(main_win_evas_object_get(wn));
+
+   return EINA_TRUE;
+}
+
+void
+app_server_shutdown(void)
+{
+   char lock_file[PATH_MAX];
+
+   if (!server)
+     return;
+
+   _user_config_file_path_build(lock_file, sizeof(lock_file), ".lock");
+   ecore_file_remove(lock_file);
+
+   eo_do(server, elm_app_server_save());
+
+   if (views_eet)
+     {
+        char eet_dir[PATH_MAX];
+
+        _user_config_file_path_build(eet_dir, sizeof(eet_dir), "terms.eet");
+        terminology_item_save(views_eet, eet_dir);
+
+        terminology_item_free(views_eet);
+     }
+   app_server_eet_shutdown();
+
+   eo_unref(server);
+   server = NULL;
+}
+
+void
+_app_server_win_del_request_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   Eina_List **wins;
+
+   if (!server)
+     return;
+
+   eo_do(server, eo_base_data_get("wins", (void **)&wins));
+
+   if (eina_list_count(*wins) > 1)
+     return;
+
+   /*
+    * this way the terms of view are already alive
+    * and we can get pwd and backlog
+    */
+   app_server_shutdown();
+}
+
+static Elm_App_Server_View *
+_app_server_term_add(Term *term)
+{
+   Elm_App_Server_View *view;
+   const char *title;
+   Evas_Object *term_object;
+
+   if (_ignore_term_add)
+     return NULL;
+
+   view = eo_add_custom(ELM_APP_SERVER_VIEW_CLASS, server,
+                        elm_app_server_view_constructor(NULL));
+
+   term_object = main_term_evas_object_get(term);
+
+   title = termio_title_get(term_object);
+
+   eo_do(view, elm_app_server_view_title_set(title),
+         elm_app_server_view_window_set(
+                  main_win_evas_object_get(main_term_win_get(term))),
+         elm_app_server_view_resume(),
+         eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_CLOSED,
+                               _view_closed_cb, term),
+         eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_RESUMED,
+                               _view_resumed_cb, term),
+         eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_SAVE,
+                               _view_save_cb, term));
+
+   evas_object_smart_callback_add(term_object, "title,change",
+                                  _term_title_changed_cb, view);
+   evas_object_smart_callback_add(term_object, "icon,change",
+                                  _term_icon_changed_cb, term);
+   evas_object_data_set(term_object, "app_view", view);
+
+   return view;
+}
+
+void
+app_server_term_add(Term *term)
+{
+   Elm_App_Server_View *view;
+
+   if (!server)
+     return;
+
+   view = _app_server_term_add(term);
+   if (!view)
+     return;
+   eo_do(server, elm_app_server_view_add(view));
+}
+
+static Elm_App_Server_View *
+_app_server_create_view_cb(Elm_App_Server *server, const Eina_Value *args 
EINA_UNUSED,
+                           Eina_Stringshare **error_name,
+                           Eina_Stringshare **error_message EINA_UNUSED)
+{
+   Win *wn;
+   Term *term;
+   Elm_App_Server_View *view;
+   Eina_List **wins;
+
+   eo_do(server, eo_base_data_get("wins", (void **)&wins));
+   wn = eina_list_data_get(*wins);
+   if (!wn)
+     {
+        ERR("There is no window open");
+        *error_name = eina_stringshare_add("There is no window open");
+        return NULL;
+     }
+   term = eina_list_data_get(main_win_terms_get(wn));
+
+   _ignore_term_add = EINA_TRUE;
+   main_new(main_win_evas_object_get(wn), main_term_evas_object_get(term));
+   _ignore_term_add = EINA_FALSE;
+
+   //Term just added by main_new()
+   term = eina_list_last_data_get(main_win_terms_get(wn));
+
+   return _app_server_term_add(term);
+}
+
+static Eina_Bool
+_restore_view_cb(void *data)
+{
+   Elm_App_Server_View *view = data;
+   eo_do(view, elm_app_server_view_resume());
+   return EINA_FALSE;
+}
+
+void
+app_server_init(Eina_List **wins, Eina_Bool restore_views)
+{
+   Win *wn;
+   Eina_Iterator *views;
+   Elm_App_Server_View *view;
+   const char *title;
+   char lock_file[PATH_MAX], eet_dir[PATH_MAX];
+   FILE *f;
+
+   wn = eina_list_data_get(*wins);
+   if (!wn)
+     return;
+
+   //we only can have one instance of Terminology running app_server
+   _user_config_file_path_build(lock_file, sizeof(lock_file), ".lock");
+   if (ecore_file_exists(lock_file))
+     return;
+
+   //create lock file
+   f = fopen(lock_file, "w");
+   if (!f)
+     return;
+   fprintf(f, "locked");
+   fclose(f);
+
+   app_server_eet_init();
+   _user_config_file_path_build(eet_dir, sizeof(eet_dir), "terms.eet");
+   views_eet = terminology_item_load(eet_dir);
+   if (!views_eet)
+     views_eet = terminology_item_new(1);
+
+   title = elm_win_title_get(main_win_evas_object_get(wn));
+
+
+   server = eo_add_custom(ELM_APP_SERVER_CLASS, NULL,
+                          elm_app_server_constructor(
+                                   "org.enlightenment.Terminology",
+                                   _app_server_create_view_cb));
+
+   eo_do(server, elm_app_server_title_set(title),
+         eo_base_data_set("wins", wins, NULL),
+         elm_app_server_views_get(&views),
+         eo_event_callback_add(ELM_APP_SERVER_EV_TERMINATE,
+                               _server_terminate_cb, wins));
+   //views saved
+   EINA_ITERATOR_FOREACH(views, view)
+     {
+        if (restore_views)
+          ecore_idler_add(_restore_view_cb, view);
+        eo_do(view,
+              eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_CLOSED,
+                                    _view_closed_cb, NULL),
+              eo_event_callback_add(ELM_APP_SERVER_VIEW_EV_RESUMED,
+                                    _view_resumed_cb, NULL));
+     }
+   eina_iterator_free(views);
+}
diff --git a/src/bin/app_server.h b/src/bin/app_server.h
new file mode 100644
index 0000000..44be376
--- /dev/null
+++ b/src/bin/app_server.h
@@ -0,0 +1,8 @@
+void app_server_init(Eina_List **wins);
+void app_server_shutdown(void);
+
+void app_server_term_add(Term *term);
+
+void app_server_term_del(Evas_Object *term);
+
+void _app_server_win_del_request_cb(void *data, Evas_Object *obj, void 
*event_info);
diff --git a/src/bin/app_server_eet.c b/src/bin/app_server_eet.c
new file mode 100644
index 0000000..0339741
--- /dev/null
+++ b/src/bin/app_server_eet.c
@@ -0,0 +1,255 @@
+/* This file has been automatically generated by geneet.py */
+/*                      DO NOT MODIFY                      */
+
+#include <limits.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "app_server_eet.h"
+
+struct _Term_Item {
+    const char * id;
+    const char * dir;
+};
+
+struct _Terminology_Item {
+    unsigned int version;
+    Eina_Hash * term_entries;
+    const char *__eet_filename;
+};
+
+static const char TERM_ITEM_ENTRY[] = "term_item";
+static const char TERMINOLOGY_ITEM_ENTRY[] = "terminology_item";
+
+static Eet_Data_Descriptor *_term_item_descriptor = NULL;
+static Eet_Data_Descriptor *_terminology_item_descriptor = NULL;
+
+static inline void
+_term_item_init(void)
+{
+    Eet_Data_Descriptor_Class eddc;
+
+    if (_term_item_descriptor) return;
+
+    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Term_Item);
+    _term_item_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+    EET_DATA_DESCRIPTOR_ADD_BASIC(_term_item_descriptor, Term_Item, "id", id, 
EET_T_STRING);
+    EET_DATA_DESCRIPTOR_ADD_BASIC(_term_item_descriptor, Term_Item, "dir", 
dir, EET_T_STRING);
+}
+
+static inline void
+_term_item_shutdown(void)
+{
+    if (!_term_item_descriptor) return;
+    eet_data_descriptor_free(_term_item_descriptor);
+    _term_item_descriptor = NULL;
+}
+
+Term_Item *
+term_item_new(const char * id, const char * dir)
+{
+    Term_Item *term_item = calloc(1, sizeof(Term_Item));
+
+    if (!term_item)
+       {
+          fprintf(stderr, "ERROR: could not calloc Term_Item\n");
+          return NULL;
+       }
+
+    term_item->id = eina_stringshare_add(id ? id : "");
+    term_item->dir = eina_stringshare_add(dir ? dir : "/");
+
+    return term_item;
+}
+
+void
+term_item_free(Term_Item *term_item)
+{
+    eina_stringshare_del(term_item->id);
+    eina_stringshare_del(term_item->dir);
+    free(term_item);
+}
+
+inline const char *
+term_item_id_get(const Term_Item *term_item)
+{
+    return term_item->id;
+}
+
+inline void
+term_item_id_set(Term_Item *term_item, const char *id)
+{
+    EINA_SAFETY_ON_NULL_RETURN(term_item);
+    eina_stringshare_replace(&(term_item->id), id);
+}
+
+inline const char *
+term_item_dir_get(const Term_Item *term_item)
+{
+    return term_item->dir;
+}
+
+inline void
+term_item_dir_set(Term_Item *term_item, const char *dir)
+{
+    EINA_SAFETY_ON_NULL_RETURN(term_item);
+    eina_stringshare_replace(&(term_item->dir), dir);
+}
+
+
+static inline void
+_terminology_item_init(void)
+{
+    Eet_Data_Descriptor_Class eddc;
+
+    if (_terminology_item_descriptor) return;
+
+    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Terminology_Item);
+    _terminology_item_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+    EET_DATA_DESCRIPTOR_ADD_BASIC(_terminology_item_descriptor, 
Terminology_Item, "version", version, EET_T_UINT);
+    EET_DATA_DESCRIPTOR_ADD_HASH(_terminology_item_descriptor, 
Terminology_Item, "term_entries", term_entries, _term_item_descriptor);
+}
+
+static inline void
+_terminology_item_shutdown(void)
+{
+    if (!_terminology_item_descriptor) return;
+    eet_data_descriptor_free(_terminology_item_descriptor);
+    _terminology_item_descriptor = NULL;
+}
+
+Terminology_Item *
+terminology_item_new(unsigned int version)
+{
+    Terminology_Item *terminology_item = calloc(1, sizeof(Terminology_Item));
+
+    if (!terminology_item)
+       {
+          fprintf(stderr, "ERROR: could not calloc Terminology_Item\n");
+          return NULL;
+       }
+
+    terminology_item->version = version;
+    terminology_item->term_entries = 
eina_hash_stringshared_new(EINA_FREE_CB(term_item_free));
+
+    return terminology_item;
+}
+
+void
+terminology_item_free(Terminology_Item *terminology_item)
+{
+    if (terminology_item->term_entries) 
eina_hash_free(terminology_item->term_entries);
+    free(terminology_item);
+}
+
+inline unsigned int
+terminology_item_version_get(const Terminology_Item *terminology_item)
+{
+    return terminology_item->version;
+}
+
+inline void
+terminology_item_version_set(Terminology_Item *terminology_item, unsigned int 
version)
+{
+    EINA_SAFETY_ON_NULL_RETURN(terminology_item);
+    terminology_item->version = version;
+}
+
+void
+terminology_item_term_entries_add(Terminology_Item *terminology_item, const 
char * id, Term_Item *term_item)
+{
+    EINA_SAFETY_ON_NULL_RETURN(terminology_item);
+    eina_hash_add(terminology_item->term_entries, id, term_item);
+}
+
+void
+terminology_item_term_entries_del(Terminology_Item *terminology_item, const 
char * id)
+{
+    EINA_SAFETY_ON_NULL_RETURN(terminology_item);
+    eina_hash_del(terminology_item->term_entries, id, NULL);
+}
+
+inline Term_Item *
+terminology_item_term_entries_get(const Terminology_Item *terminology_item, 
const char * id)
+{
+    EINA_SAFETY_ON_NULL_RETURN_VAL(terminology_item, NULL);
+    return eina_hash_find(terminology_item->term_entries, id);
+}
+
+inline Eina_Hash *
+terminology_item_term_entries_hash_get(const Terminology_Item 
*terminology_item)
+{
+    EINA_SAFETY_ON_NULL_RETURN_VAL(terminology_item, NULL);
+    return terminology_item->term_entries;
+}
+
+void
+terminology_item_term_entries_modify(Terminology_Item *terminology_item, const 
char * key, void *value)
+{
+    EINA_SAFETY_ON_NULL_RETURN(terminology_item);
+    eina_hash_modify(terminology_item->term_entries, key, value);
+}
+
+Terminology_Item *
+terminology_item_load(const char *filename)
+{
+    Terminology_Item *terminology_item = NULL;
+    Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
+    if (!ef)
+      {
+        fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
+        return NULL;
+      }
+
+    terminology_item = eet_data_read(ef, _terminology_item_descriptor, 
TERMINOLOGY_ITEM_ENTRY);
+    if (!terminology_item) goto end;
+    terminology_item->__eet_filename = eina_stringshare_add(filename);
+
+    if (!terminology_item->term_entries) terminology_item->term_entries = 
eina_hash_stringshared_new(EINA_FREE_CB(term_item_free));
+
+end:
+    eet_close(ef);
+    return terminology_item;
+}
+
+Eina_Bool
+terminology_item_save(Terminology_Item *terminology_item, const char *filename)
+{
+    Eet_File *ef;
+    Eina_Bool ret;
+
+    if (filename) 
eina_stringshare_replace(&(terminology_item->__eet_filename), filename);
+    else if (terminology_item->__eet_filename) filename = 
terminology_item->__eet_filename;
+    else return EINA_FALSE;
+
+    ef = eet_open(filename, EET_FILE_MODE_READ_WRITE);
+    if (!ef)
+       {
+          fprintf(stderr, "ERROR: could not open '%s' for write\n", filename);
+          return EINA_FALSE;
+       }
+
+    ret = !!eet_data_write(ef, _terminology_item_descriptor, 
TERMINOLOGY_ITEM_ENTRY, terminology_item, EINA_TRUE);
+    eet_close(ef);
+
+    return ret;
+}
+
+void
+app_server_eet_init(void)
+{
+    _term_item_init();
+    _terminology_item_init();
+}
+
+void
+app_server_eet_shutdown(void)
+{
+    _term_item_shutdown();
+    _terminology_item_shutdown();
+}
+
diff --git a/src/bin/app_server_eet.h b/src/bin/app_server_eet.h
new file mode 100644
index 0000000..3809caa
--- /dev/null
+++ b/src/bin/app_server_eet.h
@@ -0,0 +1,41 @@
+/* This file has been automatically generated by geneet.py */
+/*                      DO NOT MODIFY                      */
+
+#ifndef __TERMINOLOGY_EET_H__
+#define __TERMINOLOGY_EET_H__
+
+#include <Eina.h>
+#include <Eet.h>
+
+typedef struct _Term_Item Term_Item;
+typedef struct _Terminology_Item Terminology_Item;
+
+/* Term_Item */
+Term_Item *term_item_new(const char * id, const char * dir);
+void term_item_free(Term_Item *term_item);
+
+void term_item_id_set(Term_Item *term_item, const char * id);
+const char * term_item_id_get(const Term_Item *term_item);
+void term_item_dir_set(Term_Item *term_item, const char * dir);
+const char * term_item_dir_get(const Term_Item *term_item);
+
+/* Terminology_Item */
+Terminology_Item *terminology_item_new(unsigned int version);
+void terminology_item_free(Terminology_Item *terminology_item);
+
+void terminology_item_version_set(Terminology_Item *terminology_item, unsigned 
int version);
+unsigned int terminology_item_version_get(const Terminology_Item 
*terminology_item);
+void terminology_item_term_entries_add(Terminology_Item *terminology_item, 
const char * id, Term_Item *term_item);
+void terminology_item_term_entries_del(Terminology_Item *terminology_item, 
const char * id);
+Term_Item *terminology_item_term_entries_get(const Terminology_Item 
*terminology_item, const char * key);
+Eina_Hash *terminology_item_term_entries_hash_get(const Terminology_Item 
*terminology_item);
+void terminology_item_term_entries_modify(Terminology_Item *terminology_item, 
const char * key, void *value);
+
+Terminology_Item *terminology_item_load(const char *filename);
+Eina_Bool terminology_item_save(Terminology_Item *terminology_item, const char 
*filename);
+
+/* Global initializer / shutdown functions */
+void app_server_eet_init(void);
+void app_server_eet_shutdown(void);
+
+#endif /* __TERMINOLOGY_EET_H__ */
diff --git a/src/bin/config.c b/src/bin/config.c
index 2244120..34a9e0d 100644
--- a/src/bin/config.c
+++ b/src/bin/config.c
@@ -91,6 +91,11 @@ config_init(void)
      (edd_base, Config, "cg_height", cg_height, EET_T_INT);
    EET_DATA_DESCRIPTOR_ADD_BASIC
      (edd_base, Config, "drag_links", drag_links, EET_T_UCHAR);
+   EET_DATA_DESCRIPTOR_ADD_BASIC
+     (edd_base, Config, "application_server", application_server, EET_T_UCHAR);
+   EET_DATA_DESCRIPTOR_ADD_BASIC
+     (edd_base, Config, "application_server_restore_views",
+      application_server_restore_views, EET_T_UCHAR);
 }
 
 void
@@ -169,6 +174,8 @@ config_sync(const Config *config_src, Config *config)
    config->mute = config_src->mute;
    config->urg_bell = config_src->urg_bell;
    config->multi_instance = config_src->multi_instance;
+   config->application_server = config_src->application_server;
+   config->application_server_restore_views = 
config_src->application_server_restore_views;
    config->temporary = config_src->temporary;
    config->custom_geometry = config_src->custom_geometry;
    config->cg_width = config_src->cg_width;
@@ -425,6 +432,8 @@ config_load(const char *key)
              config->mute = EINA_FALSE;
              config->urg_bell = EINA_TRUE;
              config->multi_instance = EINA_FALSE;
+             config->application_server = EINA_FALSE;
+             config->application_server_restore_views = EINA_FALSE;
              config->custom_geometry = EINA_FALSE;
              config->cg_width = 80;
              config->cg_height = 24;
@@ -473,6 +482,8 @@ config_fork(Config *config)
    CPY(mute);
    CPY(urg_bell);
    CPY(multi_instance);
+   CPY(application_server);
+   CPY(application_server_restore_views);
    CPY(custom_geometry);
    CPY(cg_width);
    CPY(cg_height);
diff --git a/src/bin/config.h b/src/bin/config.h
index a40b207..78446f5 100644
--- a/src/bin/config.h
+++ b/src/bin/config.h
@@ -40,6 +40,8 @@ struct _Config
    Eina_Bool         mute;
    Eina_Bool         urg_bell;
    Eina_Bool         multi_instance;
+   Eina_Bool         application_server;
+   Eina_Bool         application_server_restore_views;
    Eina_Bool         custom_geometry;
    Eina_Bool         drag_links;
    int               cg_width;
diff --git a/src/bin/main.c b/src/bin/main.c
index fa65df3..625f286 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -592,6 +592,8 @@ main_close(Evas_Object *win, Evas_Object *term)
    Eina_List *l;
    const char *slot = PANES_TOP;
 
+   app_server_term_del(term);
+
    if (!sp) return;
    if (!sp->term) return;
    if (sp->sel) _sel_restore(sp);
@@ -2194,6 +2196,7 @@ main_term_new(Win *wn, Config *config, const char *cmd,
 //        edje_object_signal_emit(term->base, "focus,in", "terminology");
      }
    wn->terms = eina_list_append(wn->terms, term);
+   app_server_term_add(term);
    
    return term;
 }
@@ -2935,6 +2938,10 @@ remote:
      }
 
    config = config_fork(config);
+
+   if (config->application_server)
+     app_server_init(&wins, config->application_server_restore_views);
+
    term = main_term_new(wn, config, cmd, login_shell, cd,
                         size_w, size_h, hold);
    if (!term)
@@ -2947,7 +2954,7 @@ remote:
         edje_object_part_swallow(wn->base, "terminology.content", term->bg);
         _cb_size_hint(term, evas_object_evas_get(wn->win), term->term, NULL);
      }
-   
+
    sp = wn->split = calloc(1, sizeof(Split));
    sp->wn = wn;
    sp->term = term;
@@ -2976,6 +2983,8 @@ remote:
 
    elm_run();
 
+   app_server_shutdown();
+
    ty_dbus_shutdown();
  end:
 #if (ECORE_VERSION_MAJOR > 1) || (ECORE_VERSION_MINOR >= 8)
diff --git a/src/bin/options_behavior.c b/src/bin/options_behavior.c
index 00ebcd9..47b39d0 100644
--- a/src/bin/options_behavior.c
+++ b/src/bin/options_behavior.c
@@ -86,6 +86,64 @@ _cb_op_behavior_multi_instance_chg(void *data, Evas_Object 
*obj, void *event EIN
 }
 
 static void
+_cb_op_behavior_application_server_restore_views_chg(void *data, Evas_Object 
*obj,
+                                                     void *event EINA_UNUSED)
+{
+   Evas_Object *term = data;
+   Config *config = termio_config_get(term);
+   config->application_server_restore_views = elm_check_state_get(obj);
+   config_save(config, NULL);
+}
+
+static void
+_behavior_option_restore_opened_views_add(Evas_Object *term,
+                                                      Evas_Object *check)
+{
+   Evas_Object *bx = evas_object_data_get(check, "box");
+   Evas_Object *o;
+   Config *config = termio_config_get(term);
+
+   o = elm_check_add(bx);
+   evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
+   elm_object_text_set(o, "Restore opened views");
+   elm_check_state_set(o, config->application_server_restore_views);
+   elm_box_pack_after(bx, o, check);
+   evas_object_show(o);
+   evas_object_data_set(check, "restore_views", o);
+   evas_object_smart_callback_add(o, "changed",
+                                  
_cb_op_behavior_application_server_restore_views_chg,
+                                  term);
+}
+
+
+static void
+_behavior_option_restore_opened_views_del(Evas_Object *check)
+{
+   Evas_Object *o = evas_object_data_del(check, "restore_views");
+   if (o)
+     evas_object_del(o);
+}
+
+static void
+_cb_op_behavior_application_server_chg(void *data, Evas_Object *obj, void 
*event EINA_UNUSED)
+{
+   Evas_Object *term = data;
+   Config *config = termio_config_get(term);
+   Eina_Bool old = config->application_server;
+   config->application_server = elm_check_state_get(obj);
+
+   if (old == config->application_server)
+     return;
+
+   if (!config->application_server)
+     _behavior_option_restore_opened_views_del(obj);
+   else
+     _behavior_option_restore_opened_views_add(term, obj);
+   config_save(config, NULL);
+}
+
+static void
 _cb_op_behavior_wsep_chg(void *data, Evas_Object *obj, void *event EINA_UNUSED)
 {
    Evas_Object *term = data;
@@ -267,6 +325,20 @@ options_behavior(Evas_Object *opbox, Evas_Object *term)
    o = elm_check_add(bx);
    evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
    evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
+   elm_object_text_set(o, "Enable application server");
+   elm_check_state_set(o, config->application_server);
+   elm_box_pack_end(bx, o);
+   evas_object_show(o);
+   evas_object_smart_callback_add(o, "changed",
+                                  _cb_op_behavior_application_server_chg, 
term);
+
+   evas_object_data_set(o, "box", bx);
+   if (config->application_server)
+     _behavior_option_restore_opened_views_add(term, o);
+
+   o = elm_check_add(bx);
+   evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
+   evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
    elm_object_text_set(o, "Multiple instances, one process");
    elm_check_state_set(o, config->multi_instance);
    elm_box_pack_end(bx, o);
diff --git a/src/bin/win.c b/src/bin/win.c
index f5ca624..51c2e3c 100644
--- a/src/bin/win.c
+++ b/src/bin/win.c
@@ -1,6 +1,8 @@
 #include <Elementary.h>
 #include "win.h"
 #include "config.h"
+#include "main.h"
+#include "app_server.h"
 
 Evas_Object *
 tg_win_add(const char *name, const char *role, const char *title, const char 
*icon_name)
@@ -17,6 +19,9 @@ tg_win_add(const char *name, const char *role, const char 
*title, const char *ic
    elm_win_icon_name_set(win, icon_name);
    if (role) elm_win_role_set(win, role);
    
+   evas_object_smart_callback_add(win, "delete,request",
+                                  _app_server_win_del_request_cb, win);
+
    elm_win_autodel_set(win, EINA_TRUE);
    
    o = evas_object_image_add(evas_object_evas_get(win));

-- 


Reply via email to