Fix PLM issue P120724-6223, P120726-4241(duplicated)
[framework/uifw/elementary.git] / src / lib / elm_win.c
index 5389ddd..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;
 
@@ -60,6 +78,12 @@ struct _Elm_Win
         Eina_Bool top_animate : 1;
         Eina_Bool geometry_changed : 1;
      } focus_highlight;
+   struct
+   {
+      const char  *name;
+      Ecore_Timer *timer;
+      Eina_List   *names;
+   } profile;
 
    Evas_Object *icon;
    const char *title;
@@ -79,6 +103,7 @@ struct _Elm_Win
    Eina_Bool fullscreen : 1;
    Eina_Bool maximized : 1;
    Eina_Bool skip_focus : 1;
+   Eina_Bool floating : 1;
 };
 
 static const char *widtype = NULL;
@@ -128,6 +153,7 @@ static const char SIG_FULLSCREEN[] = "fullscreen";
 static const char SIG_UNFULLSCREEN[] = "unfullscreen";
 static const char SIG_MAXIMIZED[] = "maximized";
 static const char SIG_UNMAXIMIZED[] = "unmaximized";
+static const char SIG_PROFILE_CHANGED[] = "profile,changed";
 
 static const Evas_Smart_Cb_Description _signals[] = {
    {SIG_DELETE_REQUEST, ""},
@@ -143,6 +169,7 @@ static const Evas_Smart_Cb_Description _signals[] = {
    {SIG_UNFULLSCREEN, ""},
    {SIG_MAXIMIZED, ""},
    {SIG_UNMAXIMIZED, ""},
+   {SIG_PROFILE_CHANGED, ""},
    {NULL, NULL}
 };
 
@@ -172,7 +199,7 @@ _shot_delay_get(Elm_Win *win)
                   *pd = *p;
                }
              *pd = 0;
-             v = atof(d);
+             v = _elm_atof(d);
              free(d);
              return v;
           }
@@ -419,6 +446,71 @@ _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
+_elm_win_profile_update(Ecore_Evas *ee)
+{
+   Evas_Object *obj = ecore_evas_object_associate_get(ee);
+   Elm_Win *win;
+
+   if (!obj) return;
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+
+   if (win->profile.timer)
+     ecore_timer_del(win->profile.timer);
+   win->profile.timer = NULL;
+
+   /* TODO: We need the ability to bind a profile to a specific window.
+    * Elementary's configuration still has a single global profile for the app.
+    */
+   _elm_config_profile_set(win->profile.name);
+
+   evas_object_smart_callback_call(win->win_obj, SIG_PROFILE_CHANGED, NULL);
+}
+
+static Eina_Bool
+_elm_win_profile_change_delay(void *data)
+{
+   Elm_Win *win = data;
+   const char *profile;
+   Eina_Bool changed = EINA_FALSE;
+
+   profile = eina_list_nth(win->profile.names, 0);
+   if (profile)
+     {
+        if (win->profile.name)
+          {
+             if (strcmp(win->profile.name, profile))
+               {
+                  eina_stringshare_replace(&(win->profile.name), profile);
+                  changed = EINA_TRUE;
+               }
+          }
+        else
+          {
+             win->profile.name = eina_stringshare_add(profile);
+             changed = EINA_TRUE;
+          }
+     }
+   win->profile.timer = NULL;
+   if (changed) _elm_win_profile_update(win->ee);
+   return EINA_FALSE;
 }
 
 static void
@@ -431,6 +523,8 @@ _elm_win_state_change(Ecore_Evas *ee)
    Eina_Bool ch_iconified = EINA_FALSE;
    Eina_Bool ch_fullscreen = EINA_FALSE;
    Eina_Bool ch_maximized = EINA_FALSE;
+   Eina_Bool ch_profile = EINA_FALSE;
+   const char *profile;
 
    if (!(obj = ecore_evas_object_associate_get(ee))) return;
 
@@ -461,6 +555,24 @@ _elm_win_state_change(Ecore_Evas *ee)
         win->maximized = ecore_evas_maximized_get(win->ee);
         ch_maximized = EINA_TRUE;
      }
+   profile = ecore_evas_profile_get(win->ee);
+   if ((profile) &&
+       _elm_config_profile_exists(profile))
+     {
+        if (win->profile.name)
+          {
+             if (strcmp(win->profile.name, profile))
+               {
+                  eina_stringshare_replace(&(win->profile.name), profile);
+                  ch_profile = EINA_TRUE;
+               }
+          }
+        else
+          {
+             win->profile.name = eina_stringshare_add(profile);
+             ch_profile = EINA_TRUE;
+          }
+     }
    if ((ch_withdrawn) || (ch_iconified))
      {
         if (win->withdrawn)
@@ -491,6 +603,10 @@ _elm_win_state_change(Ecore_Evas *ee)
         else
           evas_object_smart_callback_call(win->win_obj, SIG_UNMAXIMIZED, NULL);
      }
+   if (ch_profile)
+     {
+        _elm_win_profile_update(win->ee);
+     }
 }
 
 static Eina_Bool
@@ -509,10 +625,8 @@ _elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_O
    if (list)
      {
         if (!(items = elm_widget_focus_custom_chain_get(obj)))
-          {
-             if (!list) return EINA_FALSE;
-             items = list;
-          }
+          items = list;
+
         list_data_get = eina_list_data_get;
 
         elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
@@ -520,7 +634,6 @@ _elm_win_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_O
         if (*next)
           return EINA_TRUE;
      }
-
    *next = (Evas_Object *)obj;
    return EINA_FALSE;
 }
@@ -614,10 +727,18 @@ _elm_win_obj_callback_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UN
 }
 
 static void
+_elm_win_obj_callback_img_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Win *win = data;
+   win->img_obj = NULL;
+}
+
+static void
 _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_info __UNUSED__)
 {
    Elm_Win *win = data;
    Evas_Object *child, *child2 = NULL;
+   const char *str;
 
    if (win->parent)
      {
@@ -674,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();
@@ -684,6 +819,8 @@ _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_inf
 
    if (win->img_obj)
      {
+        evas_object_event_callback_del_full
+           (win->img_obj, EVAS_CALLBACK_DEL, _elm_win_obj_callback_img_obj_del, win);
         win->img_obj = NULL;
      }
    else
@@ -703,6 +840,10 @@ _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_inf
    if (win->role) eina_stringshare_del(win->role);
    if (win->icon) evas_object_del(win->icon);
 
+   EINA_LIST_FREE(win->profile.names, str) eina_stringshare_del(str);
+   if (win->profile.name) eina_stringshare_del(win->profile.name);
+   if (win->profile.timer) ecore_timer_del(win->profile.timer);
+
    free(win);
 
    if ((!_elm_win_list) &&
@@ -716,15 +857,6 @@ _elm_win_obj_callback_del(void *data, Evas *e, Evas_Object *obj, void *event_inf
      }
 }
 
-static void
-_elm_win_obj_callback_img_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
-{
-   Elm_Win *win = data;
-   if (!win->img_obj) return;
-   evas_object_event_callback_del_full
-      (win->img_obj, EVAS_CALLBACK_DEL, _elm_win_obj_callback_img_obj_del, win);
-   evas_object_del(win->img_obj);
-}
 
 static void
 _elm_win_obj_callback_parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
@@ -799,6 +931,8 @@ _elm_win_obj_callback_move(void *data, Evas *e __UNUSED__, Evas_Object *obj, voi
         evas_object_geometry_get(obj, &x, &y, NULL, NULL);
         win->screen.x = x;
         win->screen.y = y;
+
+        /* FIXME: We should update ecore_wl_window_location here !! */
      }
    else if (win->img_obj)
      {
@@ -1161,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)
@@ -1198,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
@@ -1566,8 +1824,13 @@ _elm_win_frame_cb_move_start(void *data, Evas_Object *obj __UNUSED__, const char
    if (!(win = data)) return;
    /* FIXME: Change mouse pointer */
 
-   /* NB: 0,0 are dummy values. Wayland handles the move by itself */
-   ecore_evas_move(win->ee, 0, 0);
+   /* NB: Wayland handles moving surfaces by itself so we cannot 
+    * specify a specific x/y we want. Instead, we will pass in the 
+    * existing x/y values so they can be recorded as 'previous' position. 
+    * The new position will get updated automatically when the move is 
+    * finished */
+
+   ecore_evas_wayland_move(win->ee, win->screen.x, win->screen.y);
 }
 
 static void
@@ -2130,7 +2393,7 @@ elm_win_title_set(Evas_Object *obj, const char *title)
    eina_stringshare_replace(&(win->title), title);
    ecore_evas_title_set(win->ee, win->title);
    if (win->frame_obj)
-     edje_object_part_text_set(win->frame_obj, "elm.text.title", win->title);
+     edje_object_part_text_escaped_set(win->frame_obj, "elm.text.title", win->title);
 }
 
 EAPI const char *
@@ -2533,6 +2796,69 @@ elm_win_withdrawn_get(const Evas_Object *obj)
 }
 
 EAPI void
+elm_win_profiles_set(Evas_Object *obj, const char **profiles, unsigned int num_profiles)
+{
+   Elm_Win *win;
+   char **profiles_int;
+   const char *str;
+   unsigned int i, num;
+   Eina_List *l;
+
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (!profiles) return;
+
+   if (win->profile.timer) ecore_timer_del(win->profile.timer);
+   win->profile.timer = ecore_timer_add(0.1, _elm_win_profile_change_delay, win);
+   EINA_LIST_FREE(win->profile.names, str) eina_stringshare_del(str);
+
+   for (i = 0; i < num_profiles; i++)
+     {
+        if ((profiles[i]) &&
+            _elm_config_profile_exists(profiles[i]))
+          {
+             str = eina_stringshare_add(profiles[i]);
+             win->profile.names = eina_list_append(win->profile.names, str);
+          }
+     }
+
+   num = eina_list_count(win->profile.names);
+   profiles_int = alloca(num * sizeof(char *));
+
+   if (profiles_int)
+     {
+        i = 0;
+        EINA_LIST_FOREACH(win->profile.names, l, str)
+          {
+             if (str)
+               profiles_int[i] = strdup(str);
+             else
+               profiles_int[i] = NULL;
+             i++;
+          }
+        ecore_evas_profiles_set(win->ee, (const char **)profiles_int, i);
+        for (i = 0; i < num; i++)
+          {
+             if (profiles_int[i]) free(profiles_int[i]);
+          }
+     }
+   else
+     ecore_evas_profiles_set(win->ee, profiles, num_profiles);
+}
+
+EAPI const char *
+elm_win_profile_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return NULL;
+
+   return win->profile.name;
+}
+
+EAPI void
 elm_win_urgent_set(Evas_Object *obj, Eina_Bool urgent)
 {
    Elm_Win *win;
@@ -2781,6 +3107,13 @@ elm_win_keyboard_win_get(const Evas_Object *obj)
    return EINA_FALSE;
 }
 
+// WRAPPER: Temperary added.
+EAPI void
+elm_win_indicator_state_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode)
+{
+   elm_win_indicator_mode_set(obj, mode);
+}
+
 EAPI void
 elm_win_indicator_mode_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode)
 {
@@ -2806,6 +3139,13 @@ elm_win_indicator_mode_set(Evas_Object *obj, Elm_Win_Indicator_Mode mode)
 #endif
 }
 
+// WRAPPER: Temperary added.
+EAPI Elm_Win_Indicator_Mode
+elm_win_indicator_state_get(const Evas_Object *obj)
+{
+   return elm_win_indicator_mode_get(obj);
+}
+
 EAPI Elm_Win_Indicator_Mode
 elm_win_indicator_mode_get(const Evas_Object *obj)
 {
@@ -3242,7 +3582,7 @@ _elm_inwin_text_set_hook(Evas_Object *obj, const char *item, const char *text)
    Widget_Data *wd = elm_widget_data_get(obj);
 
    if (!wd || !item) return;
-   edje_object_part_text_set(wd->frm, item, text);
+   edje_object_part_text_escaped_set(wd->frm, item, text);
    _sizing_eval(obj);
 }
 
@@ -3429,3 +3769,40 @@ elm_win_xwindow_get(const Evas_Object *obj)
 #endif
    return 0;
 }
+
+EAPI void
+elm_win_floating_mode_set(Evas_Object *obj, Eina_Bool floating)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   win = elm_widget_data_get(obj);
+   if (!win) return;
+   if (floating == win->floating) return;
+#ifdef HAVE_ELEMENTARY_X
+   _elm_win_xwindow_get(win);
+#endif
+   win->floating = floating;
+#ifdef HAVE_ELEMENTARY_X
+   if (win->xwin)
+     {
+        if (win->floating)
+          ecore_x_e_illume_window_state_set
+             (win->xwin, ECORE_X_ILLUME_WINDOW_STATE_FLOATING);
+        else
+          ecore_x_e_illume_window_state_set
+             (win->xwin, ECORE_X_ILLUME_WINDOW_STATE_NORMAL);
+     }
+#endif
+}
+
+EAPI Eina_Bool
+elm_win_floating_mode_get(const Evas_Object *obj)
+{
+   Elm_Win *win;
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   win = elm_widget_data_get(obj);
+   if (!win) return EINA_FALSE;
+
+   return win->floating;
+}
+