Hello, All.

It is approach to integrate places functionality (and more) to efm2.

Improvements to efm2 hal messages processing API.

1. Added E_FM_OP_MOUNT_ERROR and E_FM_OP_UNMOUNT_ERROR slave signals.
   These signals occurs when mount or umount call to hal via d-bus
   completing with error.
2. Added mount and unmount error dialogs to efm2.
3. Completed mount_fail, umount_ok and umount_fail callbacks in e_fm_hal.
   mount_fail is called when error from d-bus received or mount timeout reached.
   umount_ok is called when volume successfully unmounted or removed.
   unmount_fail is called when error from d-bus received.
4. On hal errors corresponding efm2 windows closing or fallback to favorites
   (when open dirs in place activated).
5. On volume removing (for example, unmount from command line) corresponding
   efm2 windows closing.
6. Fixed linking to already mounted volumes when new efm2 windows opened or
   directory changed (when open dirs in place activated).
7. Only volumes mounted with efm2 will be unmounting when last efm2 window
   of it volume is closed.

Now, all e_fm2_hal routines estimating that not only efm2 and e17 can perform
operations with storages and volumes. Next, we need GUI to operate with volumes 
by hands as it in others DE.


Sincerely yours, Sergey.

--
Jabber/XMPP: sergey.semer...@gmail.com
Cellular: +7-909-206-5992
Index: e/src/bin/e_fm.c
===================================================================
--- e/src/bin/e_fm.c	(revision 40767)
+++ e/src/bin/e_fm.c	(working copy)
@@ -359,6 +359,8 @@
 static void _e_fm_error_ignore_this_cb(void *data, E_Dialog *dialog);
 static void _e_fm_error_ignore_all_cb(void *data, E_Dialog *dialog);
 
+static void _e_fm_hal_error_dialog(const char *title, const char *msg, const char *pstr);
+
 static void _e_fm2_file_delete(Evas_Object *obj);
 static void _e_fm2_file_delete_menu(void *data, E_Menu *m, E_Menu_Item *mi);
 static void _e_fm2_file_delete_delete_cb(void *obj);
@@ -809,15 +811,31 @@
 
    sd = evas_object_smart_data_get(data);
    if (!sd) return; // safety
-   /* FIXME; some dialog */
    if (sd->mount)
      {
-	e_fm2_hal_unmount(sd->mount);
+        // At this moment E_Fm2_Mount object already deleted in e_fm_hal.c
 	sd->mount = NULL;
-	evas_object_smart_callback_call(data, "dir_deleted", NULL);
+        if (sd->config->view.open_dirs_in_place)
+           e_fm2_path_set(data, "favorites", "/");
+        else
+           evas_object_smart_callback_call(data, "dir_deleted", NULL);
      }
 }
 
+static void
+_e_fm2_cb_unmount_ok(void *data)
+{
+   E_Fm2_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(data);
+   if (!sd) return;
+   if (sd->mount)
+     {
+        sd->mount = NULL;
+        evas_object_smart_callback_call(data, "dir_deleted", NULL);
+     }
+}
+
 void
 _e_fm2_path_parent_set(Evas_Object *obj, const char *path)
 {
@@ -945,7 +963,7 @@
 	if (v)
 	  sd->mount = e_fm2_hal_mount(v,
 				     _e_fm2_cb_mount_ok, _e_fm2_cb_mount_fail,
-				     NULL, NULL, obj);
+				     _e_fm2_cb_unmount_ok, NULL, obj);
      }
    else if (sd->config->view.open_dirs_in_place == 0)
      {
@@ -954,7 +972,7 @@
 	if (m)
 	  sd->mount = e_fm2_hal_mount(m->volume,
 				     _e_fm2_cb_mount_ok, _e_fm2_cb_mount_fail,
-				     NULL, NULL, obj);
+				     _e_fm2_cb_unmount_ok, NULL, obj);
      }
 
    if (!sd->mount || sd->mount->mounted)
@@ -2944,15 +2962,42 @@
 
 	     udi = e->data;
 	     v = e_fm2_hal_volume_find(udi);
-	     if (v)
-	       {
-		  v->mounted = 0;
-		  if (v->mount_point) free(v->mount_point);
-		  v->mount_point = NULL;
-	       }
+	     if (v) e_fm2_hal_mount_del(v);
 	  }
 	break;
 
+      case E_FM_OP_MOUNT_ERROR:/*mount error*/
+        if (e->data && (e->size > 1))
+          {
+             E_Volume *v;
+             char *udi;
+
+             udi = e->data;
+             v = e_fm2_hal_volume_find(udi);
+             if (v) 
+               {
+                  _e_fm_hal_error_dialog(_("Mount Error"), _("Can't mount device"), e->data);
+                  e_fm2_hal_mount_fail(v);
+               }
+          }
+        break;
+        
+      case E_FM_OP_UNMOUNT_ERROR:/*unmount error*/
+        if (e->data && (e->size > 1))
+          {
+             E_Volume *v;
+             char *udi;
+
+             udi = e->data;
+             v = e_fm2_hal_volume_find(udi);
+             if (v)
+               {
+                  _e_fm_hal_error_dialog(_("Unmount Error"), _("Can't unmount device"), e->data);
+                  e_fm2_hal_unmount_fail(v);
+               }
+          }
+        break;
+        
       case E_FM_OP_ERROR:/*error*/
 	 printf("%s:%s(%d) Error from slave #%d: %s\n", __FILE__, __FUNCTION__, __LINE__, e->ref, (char *)e->data);
 	 _e_fm_error_dialog(e->ref, e->data);
@@ -9002,6 +9047,37 @@
 }
 
 static void
+_e_fm_hal_error_dialog(const char *title, const char *msg, const char *pstr)
+{
+   E_Manager *man;
+   E_Container *con;
+   E_Dialog *dialog;
+   char text[4096];
+   const char *u, *d, *n, *m;
+
+   man = e_manager_current_get();
+   if (!man) return;
+   con = e_container_current_get(man);
+   if (!con) return;
+
+   dialog = e_dialog_new(con, "E", "_fm_hal_error_dialog");
+   e_dialog_title_set(dialog, title);
+   e_dialog_icon_set(dialog, "drive-harddisk", 64);
+   e_dialog_button_add(dialog, _("OK"), NULL, NULL, NULL);
+   
+   u = pstr;
+   d = pstr += strlen(pstr) + 1;
+   n = pstr += strlen(pstr) + 1;
+   m = pstr += strlen(pstr) + 1;
+   snprintf(text, sizeof(text), "%s<br>%s<br>%s<br>%s<br>%s", msg, u, d, n, m);
+   e_dialog_text_set(dialog, text);
+
+   e_win_centered_set(dialog->win, 1);
+   e_dialog_button_focus_num(dialog, 0);
+   e_dialog_show(dialog);
+}
+
+static void
 _e_fm2_file_properties(void *data, E_Menu *m, E_Menu_Item *mi)
 {
    E_Fm2_Icon *ic;
Index: e/src/bin/e_fm_op.h
===================================================================
--- e/src/bin/e_fm_op.h	(revision 40767)
+++ e/src/bin/e_fm_op.h	(working copy)
@@ -47,7 +47,9 @@
    E_FM_OP_SYMLINK,
    E_FM_OP_OK,
    E_FM_OP_ERROR_RETRY_ABORT,
-   E_FM_OP_REORDER
+   E_FM_OP_REORDER,
+   E_FM_OP_MOUNT_ERROR,
+   E_FM_OP_UNMOUNT_ERROR
 } E_Fm_Op_Type;
 
 #else
Index: e/src/bin/e_fm_shared.h
===================================================================
--- e/src/bin/e_fm_shared.h	(revision 40767)
+++ e/src/bin/e_fm_shared.h	(working copy)
@@ -58,6 +58,8 @@
    Eina_List *mounts;
    
    unsigned char validated;
+   
+   char auto_unmount;
 };
 
 struct _E_Fm2_Mount
Index: e/src/bin/e_fm_main.c
===================================================================
--- e/src/bin/e_fm_main.c	(revision 40767)
+++ e/src/bin/e_fm_main.c	(working copy)
@@ -189,6 +189,7 @@
 static void _e_dbus_cb_vol_prop_mount_modified(void *data, void *reply_data, DBusError *error);
 static void _e_dbus_cb_vol_mounted(void *user_data, void *method_return, DBusError *error);
 static void _e_dbus_cb_vol_unmounted(void *user_data, void *method_return, DBusError *error);
+static int  _e_dbus_format_error_msg(char **buf, E_Volume *v, DBusError *error);
 
 EAPI E_Storage *e_storage_add(const char *udi);
 EAPI void       e_storage_del(const char *udi);
@@ -720,6 +721,26 @@
    return;
 }
 
+static int
+_e_dbus_format_error_msg(char **buf, E_Volume *v, DBusError *error)
+{
+   int size, vu, vm, en;
+   char *tmp;
+   
+   vu = strlen(v->udi) + 1;
+   vm = strlen(v->mount_point) + 1;
+   en = strlen(error->name) + 1;
+   size = vu + vm + en + strlen(error->message) + 1;
+   tmp = *buf = malloc(size);
+   
+   strcpy(tmp, v->udi);
+   strcpy(tmp += vu, v->mount_point);
+   strcpy(tmp += vm, error->name);
+   strcpy(tmp += en, error->message);
+   
+   return size;
+}
+
 static void
 _e_dbus_cb_vol_prop_mount_modified(void *data, void *reply_data, DBusError *error)
 {
@@ -730,7 +751,18 @@
    if (!ret) return;
    if (dbus_error_is_set(error))
      {
+        char *buf;
+        int size;
+   
+        size = _e_dbus_format_error_msg(&buf, v, error);
+        if (v->mounted)
+           ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
+                                 0, 0, 0, buf, size);
+        else
+           ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
+                                 0, 0, 0, buf, size);
 	dbus_error_free(error);
+	free(buf);
 	return;
      }
    
@@ -834,9 +866,14 @@
    
    if (dbus_error_is_set(error))
      {
-	dbus_error_free(error);
-	return;
+        size = _e_dbus_format_error_msg(&buf, v, error);
+        ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
+                              0, 0, 0, buf, size);
+        dbus_error_free(error);
+        free(buf);
+        return;
      }
+   
    v->mounted = 1;
 //   printf("MOUNT: %s from %s\n", v->udi, v->mount_point);
    size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
@@ -870,7 +907,7 @@
 	opt = eina_list_append(opt, buf);
      }
    e_hal_device_volume_mount(_e_dbus_conn, v->udi, mount_point,
-			     v->fstype, opt, NULL, v);
+			     v->fstype, opt, _e_dbus_cb_vol_mounted, v);
    opt = eina_list_free(opt);
 }
 
@@ -883,9 +920,14 @@
 
    if (dbus_error_is_set(error))
      {
-	dbus_error_free(error);
-	return;
+        size = _e_dbus_format_error_msg(&buf, v, error);
+        ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
+                              0, 0, 0, buf, size);
+        dbus_error_free(error);
+        free(buf);
+        return;
      }
+   
    v->mounted = 0;
 //   printf("UNMOUNT: %s from %s\n", v->udi, v->mount_point);
    size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
Index: e/src/bin/e_fm_hal.c
===================================================================
--- e/src/bin/e_fm_hal.c	(revision 40767)
+++ e/src/bin/e_fm_hal.c	(working copy)
@@ -9,8 +9,12 @@
 
 static void _e_fm2_volume_write(E_Volume *v) EINA_ARG_NONNULL(1);
 static void _e_fm2_volume_erase(E_Volume *v) EINA_ARG_NONNULL(1);
+static void _e_fm2_hal_mount_free(E_Fm2_Mount *m); EINA_ARG_NONNULL(1);
 static void _e_fm2_hal_mount_ok(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
 static int  _e_fm2_hal_mount_timeout(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
+static void _e_fm2_hal_mount_fail(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
+static void _e_fm2_hal_unmount_ok(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
+static void _e_fm2_hal_unmount_fail(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
 
 static Eina_List *_e_stores = NULL;
 static Eina_List *_e_vols   = NULL;
@@ -268,11 +272,20 @@
 EAPI void
 e_fm2_hal_volume_del(E_Volume *v)
 {
+   Eina_List *l, *l_nxt;
+   E_Fm2_Mount *m;
+   
 //   printf("VOL- %s\n", v->udi);
    if (v->storage) 
      v->storage->volumes = eina_list_remove(v->storage->volumes, v);
    _e_vols = eina_list_remove(_e_vols, v);
    _e_fm2_volume_erase(v);
+   EINA_LIST_FOREACH_SAFE(v->mounts, l, l_nxt, m)
+     {
+        _e_fm2_hal_unmount_ok(m);
+        v->mounts = eina_list_remove_list(v->mounts, l);
+        _e_fm2_hal_mount_free(m);
+     }
    _e_volume_free(v);
 }
 
@@ -412,8 +425,29 @@
 }
 
 EAPI void
-e_fm2_hal_mount_del(E_Fm2_Mount *m)
+e_fm2_hal_mount_del(E_Volume *v)
 {
+   Eina_List *l, *l_nxt;
+   E_Fm2_Mount *m;
+   
+   v->mounted = 0;
+   if (v->mount_point) 
+     {
+        free(v->mount_point);
+        v->mount_point = NULL;
+     }
+
+   EINA_LIST_FOREACH_SAFE(v->mounts, l, l_nxt, m)
+     {
+        _e_fm2_hal_unmount_ok(m);
+        v->mounts = eina_list_remove_list(v->mounts, l);
+        _e_fm2_hal_mount_free(m);
+     }
+}
+
+EAPI void
+_e_fm2_hal_mount_free(E_Fm2_Mount *m)
+{
    if (!m) return;
 
    if (m->udi) eina_stringshare_del(m->udi);
@@ -469,29 +503,68 @@
    v->mounts = eina_list_prepend(v->mounts, m);
 
 //   printf("BEGIN MOUNT %p '%s'\n", m, v->mount_point);
-   
+
    if (!v->mounted)
      {
+        v->auto_unmount = 1;
 	if (m->timeout) ecore_timer_del(m->timeout);
 	m->timeout = ecore_timer_add(10.0, (int (*)(void*))_e_fm2_hal_mount_timeout, m);
 	_e_fm2_client_mount(v->udi, v->mount_point);
      }
+   else
+     {
+        v->auto_unmount = 0;
+        m->mount_point = eina_stringshare_add(v->mount_point);
+     }
+
    return m;
 }
 
 EAPI void
+e_fm2_hal_mount_fail(E_Volume *v)
+{
+   Eina_List *l, *l_nxt;
+   E_Fm2_Mount *m;
+
+   v->mounted = 0;
+   if (v->mount_point) 
+     {
+        free(v->mount_point);
+        v->mount_point = NULL;
+     }
+
+   EINA_LIST_FOREACH_SAFE(v->mounts, l, l_nxt, m)
+     {
+        _e_fm2_hal_mount_fail(m);
+        v->mounts = eina_list_remove_list(v->mounts, l);
+        _e_fm2_hal_mount_free(m);
+     }
+}
+
+EAPI void
 e_fm2_hal_unmount(E_Fm2_Mount *m)
 {
    E_Volume *v;
 
    if (!(v = m->volume)) return;
    v->mounts = eina_list_remove(v->mounts, m);
-   e_fm2_hal_mount_del(m);
+   _e_fm2_hal_mount_free(m);
 
-   if (!eina_list_count(v->mounts))
+   if (v->auto_unmount && v->mounted && !eina_list_count(v->mounts))
      _e_fm2_client_unmount(v->udi);
 }
 
+EAPI void
+e_fm2_hal_unmount_fail(E_Volume *v)
+{
+   Eina_List *l;
+
+   v->mounted = 1;
+
+   for (l = v->mounts; l; l = l->next)
+     _e_fm2_hal_unmount_fail(l->data);
+}
+
 static void
 _e_fm2_hal_mount_ok(E_Fm2_Mount *m)
 {
@@ -506,11 +579,70 @@
 //   printf("MOUNT OK '%s'\n", m->mount_point);
 }
 
+static void
+_e_fm2_hal_mount_fail(E_Fm2_Mount *m)
+{
+   m->mounted = 0;
+   if (m->mount_point)
+     {
+        eina_stringshare_del(m->mount_point);
+        m->mount_point = NULL;
+     }
+   if (m->timeout)
+     {
+        ecore_timer_del(m->timeout);
+        m->timeout = NULL;
+     }
+   if (m->mount_fail) 
+     m->mount_fail(m->data);
+}
+
+static void
+_e_fm2_hal_unmount_ok(E_Fm2_Mount *m)
+{
+   m->mounted = 0;
+   if (m->mount_point)
+     {
+        eina_stringshare_del(m->mount_point);
+        m->mount_point = NULL;
+     }
+   if (m->timeout)
+     {
+        ecore_timer_del(m->timeout);
+        m->timeout = NULL;
+     }
+   if (m->unmount_ok) 
+      m->unmount_ok(m->data);
+}
+
+static void
+_e_fm2_hal_unmount_fail(E_Fm2_Mount *m)
+{
+   m->mounted = 1;
+   if (m->timeout)
+     {
+        ecore_timer_del(m->timeout);
+        m->timeout = NULL;
+     }
+   if (m->unmount_fail) 
+     m->unmount_fail(m->data);
+}
+
 static int
 _e_fm2_hal_mount_timeout(E_Fm2_Mount *m)
 {
-   m->mount_fail(m->data);
+   E_Volume *v;
+
    m->timeout = NULL;
+   if (m->mount_fail)
+     m->mount_fail(m->data);
+   v = m->volume;
+   if (v)
+     {
+        v->mounts = eina_list_remove(v->mounts, m);
+        _e_fm2_hal_mount_free(m);
+     }
+   
    return 0;
 }
 
Index: e/src/bin/e_fm_hal.h
===================================================================
--- e/src/bin/e_fm_hal.h	(revision 40767)
+++ e/src/bin/e_fm_hal.h	(working copy)
@@ -17,13 +17,15 @@
 EAPI char        *e_fm2_hal_volume_mountpoint_get(E_Volume *v);
 
 EAPI void         e_fm2_hal_mount_add(E_Volume *v, const char *mountpoint);
-EAPI void         e_fm2_hal_mount_del(E_Fm2_Mount *m);
+EAPI void         e_fm2_hal_mount_del(E_Volume *v);
 EAPI E_Fm2_Mount *e_fm2_hal_mount_find(const char *path);
 EAPI E_Fm2_Mount *e_fm2_hal_mount(E_Volume *v,
                                   void (*mount_ok) (void *data), void (*mount_fail) (void *data), 
 				  void (*unmount_ok) (void *data), void (*unmount_fail) (void *data), 
 				  void *data);
+EAPI void         e_fm2_hal_mount_fail(E_Volume *v);
 EAPI void         e_fm2_hal_unmount(E_Fm2_Mount *m);
+EAPI void         e_fm2_hal_unmount_fail(E_Volume *v);
 
 EAPI void         e_fm2_hal_show_desktop_icons(void);
 EAPI void         e_fm2_hal_hide_desktop_icons(void);
Index: e/src/modules/fileman/e_mod_main.c
===================================================================
--- e/src/modules/fileman/e_mod_main.c	(revision 40767)
+++ e/src/modules/fileman/e_mod_main.c	(working copy)
@@ -216,21 +216,6 @@
 //~ }
 
 static void
-_mount_ok(void *data)
-{
-   E_Volume *vol = data;
-   e_fwin_new(e_container_current_get(e_manager_current_get()),
-	      NULL, vol->mount_point);
-}
-
-static void
-_mount_fail(void *data)
-{
-   //TODO make a better dialog
-   e_util_dialog_internal(_("Mount error"), _("Mount of device failed"));
-}
-
-static void
 _e_mod_menu_gtk_cb(void *data, E_Menu *m, E_Menu_Item *mi)
 {
    char *path = data;
@@ -253,8 +238,13 @@
 	if (m->zone)
 	  e_fwin_new(m->zone->container, NULL, vol->mount_point);
      }
-   else //TODO need to remove the mount?
-      e_fm2_hal_mount(vol, _mount_ok, _mount_fail, NULL, NULL, vol);
+   else
+     {
+        char buf[PATH_MAX];
+        snprintf(buf, sizeof(buf), "removable:%s", vol->udi);
+        e_fwin_new(e_container_current_get(e_manager_current_get()),
+                   buf, "/");
+     }
 }
 
 static void
Improvements to efm2 hal messages processing API.

1. Added E_FM_OP_MOUNT_ERROR and E_FM_OP_UNMOUNT_ERROR slave signals.
   These signals occurs when mount or umount call to hal via d-bus
   completing with error.
2. Added mount and unmount error dialogs to efm2.
3. Completed mount_fail, umount_ok and umount_fail callbacks in e_fm_hal.
   mount_fail is called when error from d-bus received or mount timeout reached.
   umount_ok is called when volume successfully unmounted or removed.
   unmount_fail is called when error from d-bus received.
4. On hal errors corresponding efm2 windows closing or fallback to favorites
   (when open dirs in place activated).
5. On volume removing (for example, unmount from command line) corresponding
   efm2 windows closing.
6. Fixed linking to already mounted volumes when new efm2 windows opened or
   directory changed (when open dirs in place activated).
7. Only volumes mounted with efm2 will be unmounting when last efm2 window
   of it volume is closed.

Now, all e_fm2_hal routines estimating that not only efm2 and e17 can perform
operations with storages and volumes. Next, we need GUI to operate with volumes
by hands as it in others DE.

 bin/e_fm.c                   |   98 ++++++++++++++++++++++++++---
 bin/e_fm_hal.c               |  142 +++++++++++++++++++++++++++++++++++++++++--
 bin/e_fm_hal.h               |    4 -
 bin/e_fm_main.c              |   52 ++++++++++++++-
 bin/e_fm_op.h                |    4 -
 bin/e_fm_shared.h            |    2 
 modules/fileman/e_mod_main.c |   24 ++-----
 7 files changed, 286 insertions(+), 40 deletions(-)

Index: e/src/bin/e_fm.c
===================================================================
--- e/src/bin/e_fm.c	(revision 40767)
+++ e/src/bin/e_fm.c	(working copy)
@@ -359,6 +359,8 @@
 static void _e_fm_error_ignore_this_cb(void *data, E_Dialog *dialog);
 static void _e_fm_error_ignore_all_cb(void *data, E_Dialog *dialog);
 
+static void _e_fm_hal_error_dialog(const char *title, const char *msg, const char *pstr);
+
 static void _e_fm2_file_delete(Evas_Object *obj);
 static void _e_fm2_file_delete_menu(void *data, E_Menu *m, E_Menu_Item *mi);
 static void _e_fm2_file_delete_delete_cb(void *obj);
@@ -809,15 +811,31 @@
 
    sd = evas_object_smart_data_get(data);
    if (!sd) return; // safety
-   /* FIXME; some dialog */
    if (sd->mount)
      {
-	e_fm2_hal_unmount(sd->mount);
+        // At this moment E_Fm2_Mount object already deleted in e_fm_hal.c
 	sd->mount = NULL;
-	evas_object_smart_callback_call(data, "dir_deleted", NULL);
+        if (sd->config->view.open_dirs_in_place)
+           e_fm2_path_set(data, "favorites", "/");
+        else
+           evas_object_smart_callback_call(data, "dir_deleted", NULL);
      }
 }
 
+static void
+_e_fm2_cb_unmount_ok(void *data)
+{
+   E_Fm2_Smart_Data *sd;
+
+   sd = evas_object_smart_data_get(data);
+   if (!sd) return;
+   if (sd->mount)
+     {
+        sd->mount = NULL;
+        evas_object_smart_callback_call(data, "dir_deleted", NULL);
+     }
+}
+
 void
 _e_fm2_path_parent_set(Evas_Object *obj, const char *path)
 {
@@ -945,7 +963,7 @@
 	if (v)
 	  sd->mount = e_fm2_hal_mount(v,
 				     _e_fm2_cb_mount_ok, _e_fm2_cb_mount_fail,
-				     NULL, NULL, obj);
+				     _e_fm2_cb_unmount_ok, NULL, obj);
      }
    else if (sd->config->view.open_dirs_in_place == 0)
      {
@@ -954,7 +972,7 @@
 	if (m)
 	  sd->mount = e_fm2_hal_mount(m->volume,
 				     _e_fm2_cb_mount_ok, _e_fm2_cb_mount_fail,
-				     NULL, NULL, obj);
+				     _e_fm2_cb_unmount_ok, NULL, obj);
      }
 
    if (!sd->mount || sd->mount->mounted)
@@ -2944,15 +2962,42 @@
 
 	     udi = e->data;
 	     v = e_fm2_hal_volume_find(udi);
-	     if (v)
-	       {
-		  v->mounted = 0;
-		  if (v->mount_point) free(v->mount_point);
-		  v->mount_point = NULL;
-	       }
+	     if (v) e_fm2_hal_mount_del(v);
 	  }
 	break;
 
+      case E_FM_OP_MOUNT_ERROR:/*mount error*/
+        if (e->data && (e->size > 1))
+          {
+             E_Volume *v;
+             char *udi;
+
+             udi = e->data;
+             v = e_fm2_hal_volume_find(udi);
+             if (v) 
+               {
+                  _e_fm_hal_error_dialog(_("Mount Error"), _("Can't mount device"), e->data);
+                  e_fm2_hal_mount_fail(v);
+               }
+          }
+        break;
+        
+      case E_FM_OP_UNMOUNT_ERROR:/*unmount error*/
+        if (e->data && (e->size > 1))
+          {
+             E_Volume *v;
+             char *udi;
+
+             udi = e->data;
+             v = e_fm2_hal_volume_find(udi);
+             if (v)
+               {
+                  _e_fm_hal_error_dialog(_("Unmount Error"), _("Can't unmount device"), e->data);
+                  e_fm2_hal_unmount_fail(v);
+               }
+          }
+        break;
+        
       case E_FM_OP_ERROR:/*error*/
 	 printf("%s:%s(%d) Error from slave #%d: %s\n", __FILE__, __FUNCTION__, __LINE__, e->ref, (char *)e->data);
 	 _e_fm_error_dialog(e->ref, e->data);
@@ -9002,6 +9047,37 @@
 }
 
 static void
+_e_fm_hal_error_dialog(const char *title, const char *msg, const char *pstr)
+{
+   E_Manager *man;
+   E_Container *con;
+   E_Dialog *dialog;
+   char text[4096];
+   const char *u, *d, *n, *m;
+
+   man = e_manager_current_get();
+   if (!man) return;
+   con = e_container_current_get(man);
+   if (!con) return;
+
+   dialog = e_dialog_new(con, "E", "_fm_hal_error_dialog");
+   e_dialog_title_set(dialog, title);
+   e_dialog_icon_set(dialog, "drive-harddisk", 64);
+   e_dialog_button_add(dialog, _("OK"), NULL, NULL, NULL);
+   
+   u = pstr;
+   d = pstr += strlen(pstr) + 1;
+   n = pstr += strlen(pstr) + 1;
+   m = pstr += strlen(pstr) + 1;
+   snprintf(text, sizeof(text), "%s<br>%s<br>%s<br>%s<br>%s", msg, u, d, n, m);
+   e_dialog_text_set(dialog, text);
+
+   e_win_centered_set(dialog->win, 1);
+   e_dialog_button_focus_num(dialog, 0);
+   e_dialog_show(dialog);
+}
+
+static void
 _e_fm2_file_properties(void *data, E_Menu *m, E_Menu_Item *mi)
 {
    E_Fm2_Icon *ic;
Index: e/src/bin/e_fm_op.h
===================================================================
--- e/src/bin/e_fm_op.h	(revision 40767)
+++ e/src/bin/e_fm_op.h	(working copy)
@@ -47,7 +47,9 @@
    E_FM_OP_SYMLINK,
    E_FM_OP_OK,
    E_FM_OP_ERROR_RETRY_ABORT,
-   E_FM_OP_REORDER
+   E_FM_OP_REORDER,
+   E_FM_OP_MOUNT_ERROR,
+   E_FM_OP_UNMOUNT_ERROR
 } E_Fm_Op_Type;
 
 #else
Index: e/src/bin/e_fm_shared.h
===================================================================
--- e/src/bin/e_fm_shared.h	(revision 40767)
+++ e/src/bin/e_fm_shared.h	(working copy)
@@ -58,6 +58,8 @@
    Eina_List *mounts;
    
    unsigned char validated;
+   
+   char auto_unmount;
 };
 
 struct _E_Fm2_Mount
Index: e/src/bin/e_fm_main.c
===================================================================
--- e/src/bin/e_fm_main.c	(revision 40767)
+++ e/src/bin/e_fm_main.c	(working copy)
@@ -189,6 +189,7 @@
 static void _e_dbus_cb_vol_prop_mount_modified(void *data, void *reply_data, DBusError *error);
 static void _e_dbus_cb_vol_mounted(void *user_data, void *method_return, DBusError *error);
 static void _e_dbus_cb_vol_unmounted(void *user_data, void *method_return, DBusError *error);
+static int  _e_dbus_format_error_msg(char **buf, E_Volume *v, DBusError *error);
 
 EAPI E_Storage *e_storage_add(const char *udi);
 EAPI void       e_storage_del(const char *udi);
@@ -720,6 +721,26 @@
    return;
 }
 
+static int
+_e_dbus_format_error_msg(char **buf, E_Volume *v, DBusError *error)
+{
+   int size, vu, vm, en;
+   char *tmp;
+   
+   vu = strlen(v->udi) + 1;
+   vm = strlen(v->mount_point) + 1;
+   en = strlen(error->name) + 1;
+   size = vu + vm + en + strlen(error->message) + 1;
+   tmp = *buf = malloc(size);
+   
+   strcpy(tmp, v->udi);
+   strcpy(tmp += vu, v->mount_point);
+   strcpy(tmp += vm, error->name);
+   strcpy(tmp += en, error->message);
+   
+   return size;
+}
+
 static void
 _e_dbus_cb_vol_prop_mount_modified(void *data, void *reply_data, DBusError *error)
 {
@@ -730,7 +751,18 @@
    if (!ret) return;
    if (dbus_error_is_set(error))
      {
+        char *buf;
+        int size;
+   
+        size = _e_dbus_format_error_msg(&buf, v, error);
+        if (v->mounted)
+           ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
+                                 0, 0, 0, buf, size);
+        else
+           ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
+                                 0, 0, 0, buf, size);
 	dbus_error_free(error);
+	free(buf);
 	return;
      }
    
@@ -834,9 +866,14 @@
    
    if (dbus_error_is_set(error))
      {
-	dbus_error_free(error);
-	return;
+        size = _e_dbus_format_error_msg(&buf, v, error);
+        ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_MOUNT_ERROR,
+                              0, 0, 0, buf, size);
+        dbus_error_free(error);
+        free(buf);
+        return;
      }
+   
    v->mounted = 1;
 //   printf("MOUNT: %s from %s\n", v->udi, v->mount_point);
    size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
@@ -870,7 +907,7 @@
 	opt = eina_list_append(opt, buf);
      }
    e_hal_device_volume_mount(_e_dbus_conn, v->udi, mount_point,
-			     v->fstype, opt, NULL, v);
+			     v->fstype, opt, _e_dbus_cb_vol_mounted, v);
    opt = eina_list_free(opt);
 }
 
@@ -883,9 +920,14 @@
 
    if (dbus_error_is_set(error))
      {
-	dbus_error_free(error);
-	return;
+        size = _e_dbus_format_error_msg(&buf, v, error);
+        ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_UNMOUNT_ERROR,
+                              0, 0, 0, buf, size);
+        dbus_error_free(error);
+        free(buf);
+        return;
      }
+   
    v->mounted = 0;
 //   printf("UNMOUNT: %s from %s\n", v->udi, v->mount_point);
    size = strlen(v->udi) + 1 + strlen(v->mount_point) + 1;
Index: e/src/bin/e_fm_hal.c
===================================================================
--- e/src/bin/e_fm_hal.c	(revision 40767)
+++ e/src/bin/e_fm_hal.c	(working copy)
@@ -9,8 +9,12 @@
 
 static void _e_fm2_volume_write(E_Volume *v) EINA_ARG_NONNULL(1);
 static void _e_fm2_volume_erase(E_Volume *v) EINA_ARG_NONNULL(1);
+static void _e_fm2_hal_mount_free(E_Fm2_Mount *m); EINA_ARG_NONNULL(1);
 static void _e_fm2_hal_mount_ok(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
 static int  _e_fm2_hal_mount_timeout(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
+static void _e_fm2_hal_mount_fail(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
+static void _e_fm2_hal_unmount_ok(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
+static void _e_fm2_hal_unmount_fail(E_Fm2_Mount *m) EINA_ARG_NONNULL(1);
 
 static Eina_List *_e_stores = NULL;
 static Eina_List *_e_vols   = NULL;
@@ -268,11 +272,20 @@
 EAPI void
 e_fm2_hal_volume_del(E_Volume *v)
 {
+   Eina_List *l, *l_nxt;
+   E_Fm2_Mount *m;
+   
 //   printf("VOL- %s\n", v->udi);
    if (v->storage) 
      v->storage->volumes = eina_list_remove(v->storage->volumes, v);
    _e_vols = eina_list_remove(_e_vols, v);
    _e_fm2_volume_erase(v);
+   EINA_LIST_FOREACH_SAFE(v->mounts, l, l_nxt, m)
+     {
+        _e_fm2_hal_unmount_ok(m);
+        v->mounts = eina_list_remove_list(v->mounts, l);
+        _e_fm2_hal_mount_free(m);
+     }
    _e_volume_free(v);
 }
 
@@ -412,8 +425,29 @@
 }
 
 EAPI void
-e_fm2_hal_mount_del(E_Fm2_Mount *m)
+e_fm2_hal_mount_del(E_Volume *v)
 {
+   Eina_List *l, *l_nxt;
+   E_Fm2_Mount *m;
+   
+   v->mounted = 0;
+   if (v->mount_point) 
+     {
+        free(v->mount_point);
+        v->mount_point = NULL;
+     }
+
+   EINA_LIST_FOREACH_SAFE(v->mounts, l, l_nxt, m)
+     {
+        _e_fm2_hal_unmount_ok(m);
+        v->mounts = eina_list_remove_list(v->mounts, l);
+        _e_fm2_hal_mount_free(m);
+     }
+}
+
+EAPI void
+_e_fm2_hal_mount_free(E_Fm2_Mount *m)
+{
    if (!m) return;
 
    if (m->udi) eina_stringshare_del(m->udi);
@@ -469,29 +503,68 @@
    v->mounts = eina_list_prepend(v->mounts, m);
 
 //   printf("BEGIN MOUNT %p '%s'\n", m, v->mount_point);
-   
+
    if (!v->mounted)
      {
+        v->auto_unmount = 1;
 	if (m->timeout) ecore_timer_del(m->timeout);
 	m->timeout = ecore_timer_add(10.0, (int (*)(void*))_e_fm2_hal_mount_timeout, m);
 	_e_fm2_client_mount(v->udi, v->mount_point);
      }
+   else
+     {
+        v->auto_unmount = 0;
+        m->mount_point = eina_stringshare_add(v->mount_point);
+     }
+
    return m;
 }
 
 EAPI void
+e_fm2_hal_mount_fail(E_Volume *v)
+{
+   Eina_List *l, *l_nxt;
+   E_Fm2_Mount *m;
+
+   v->mounted = 0;
+   if (v->mount_point) 
+     {
+        free(v->mount_point);
+        v->mount_point = NULL;
+     }
+
+   EINA_LIST_FOREACH_SAFE(v->mounts, l, l_nxt, m)
+     {
+        _e_fm2_hal_mount_fail(m);
+        v->mounts = eina_list_remove_list(v->mounts, l);
+        _e_fm2_hal_mount_free(m);
+     }
+}
+
+EAPI void
 e_fm2_hal_unmount(E_Fm2_Mount *m)
 {
    E_Volume *v;
 
    if (!(v = m->volume)) return;
    v->mounts = eina_list_remove(v->mounts, m);
-   e_fm2_hal_mount_del(m);
+   _e_fm2_hal_mount_free(m);
 
-   if (!eina_list_count(v->mounts))
+   if (v->auto_unmount && v->mounted && !eina_list_count(v->mounts))
      _e_fm2_client_unmount(v->udi);
 }
 
+EAPI void
+e_fm2_hal_unmount_fail(E_Volume *v)
+{
+   Eina_List *l;
+
+   v->mounted = 1;
+
+   for (l = v->mounts; l; l = l->next)
+     _e_fm2_hal_unmount_fail(l->data);
+}
+
 static void
 _e_fm2_hal_mount_ok(E_Fm2_Mount *m)
 {
@@ -506,11 +579,70 @@
 //   printf("MOUNT OK '%s'\n", m->mount_point);
 }
 
+static void
+_e_fm2_hal_mount_fail(E_Fm2_Mount *m)
+{
+   m->mounted = 0;
+   if (m->mount_point)
+     {
+        eina_stringshare_del(m->mount_point);
+        m->mount_point = NULL;
+     }
+   if (m->timeout)
+     {
+        ecore_timer_del(m->timeout);
+        m->timeout = NULL;
+     }
+   if (m->mount_fail) 
+     m->mount_fail(m->data);
+}
+
+static void
+_e_fm2_hal_unmount_ok(E_Fm2_Mount *m)
+{
+   m->mounted = 0;
+   if (m->mount_point)
+     {
+        eina_stringshare_del(m->mount_point);
+        m->mount_point = NULL;
+     }
+   if (m->timeout)
+     {
+        ecore_timer_del(m->timeout);
+        m->timeout = NULL;
+     }
+   if (m->unmount_ok) 
+      m->unmount_ok(m->data);
+}
+
+static void
+_e_fm2_hal_unmount_fail(E_Fm2_Mount *m)
+{
+   m->mounted = 1;
+   if (m->timeout)
+     {
+        ecore_timer_del(m->timeout);
+        m->timeout = NULL;
+     }
+   if (m->unmount_fail) 
+     m->unmount_fail(m->data);
+}
+
 static int
 _e_fm2_hal_mount_timeout(E_Fm2_Mount *m)
 {
-   m->mount_fail(m->data);
+   E_Volume *v;
+
    m->timeout = NULL;
+   if (m->mount_fail)
+     m->mount_fail(m->data);
+   v = m->volume;
+   if (v)
+     {
+        v->mounts = eina_list_remove(v->mounts, m);
+        _e_fm2_hal_mount_free(m);
+     }
+   
    return 0;
 }
 
Index: e/src/bin/e_fm_hal.h
===================================================================
--- e/src/bin/e_fm_hal.h	(revision 40767)
+++ e/src/bin/e_fm_hal.h	(working copy)
@@ -17,13 +17,15 @@
 EAPI char        *e_fm2_hal_volume_mountpoint_get(E_Volume *v);
 
 EAPI void         e_fm2_hal_mount_add(E_Volume *v, const char *mountpoint);
-EAPI void         e_fm2_hal_mount_del(E_Fm2_Mount *m);
+EAPI void         e_fm2_hal_mount_del(E_Volume *v);
 EAPI E_Fm2_Mount *e_fm2_hal_mount_find(const char *path);
 EAPI E_Fm2_Mount *e_fm2_hal_mount(E_Volume *v,
                                   void (*mount_ok) (void *data), void (*mount_fail) (void *data), 
 				  void (*unmount_ok) (void *data), void (*unmount_fail) (void *data), 
 				  void *data);
+EAPI void         e_fm2_hal_mount_fail(E_Volume *v);
 EAPI void         e_fm2_hal_unmount(E_Fm2_Mount *m);
+EAPI void         e_fm2_hal_unmount_fail(E_Volume *v);
 
 EAPI void         e_fm2_hal_show_desktop_icons(void);
 EAPI void         e_fm2_hal_hide_desktop_icons(void);
Index: e/src/modules/fileman/e_mod_main.c
===================================================================
--- e/src/modules/fileman/e_mod_main.c	(revision 40767)
+++ e/src/modules/fileman/e_mod_main.c	(working copy)
@@ -216,21 +216,6 @@
 //~ }
 
 static void
-_mount_ok(void *data)
-{
-   E_Volume *vol = data;
-   e_fwin_new(e_container_current_get(e_manager_current_get()),
-	      NULL, vol->mount_point);
-}
-
-static void
-_mount_fail(void *data)
-{
-   //TODO make a better dialog
-   e_util_dialog_internal(_("Mount error"), _("Mount of device failed"));
-}
-
-static void
 _e_mod_menu_gtk_cb(void *data, E_Menu *m, E_Menu_Item *mi)
 {
    char *path = data;
@@ -253,8 +238,13 @@
 	if (m->zone)
 	  e_fwin_new(m->zone->container, NULL, vol->mount_point);
      }
-   else //TODO need to remove the mount?
-      e_fm2_hal_mount(vol, _mount_ok, _mount_fail, NULL, NULL, vol);
+   else
+     {
+        char buf[PATH_MAX];
+        snprintf(buf, sizeof(buf), "removable:%s", vol->udi);
+        e_fwin_new(e_container_current_get(e_manager_current_get()),
+                   buf, "/");
+     }
 }
 
 static void
------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp asthey present alongside digital heavyweights like Barbarian
Group, R/GA, & Big Spaceship. http://www.creativitycat.com 
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to