efm2 hal handling API - full changes.

1. Added E_FM_OP_EJECT command to e_fm_main. It unmounts volume
   before eject, if it necessary.
2. Added timeouts of mounting/unmounting/ejecting media, and
   it's moved to slave e_fm_main.c. Each timeout will generate
   *_MOUNT_ERROR, *_UNMOUNT_ERROR and *_EJECT_ERROR message.
3. Added auto mount on insert media and auto showing efm2 window
   on mount volume options to filemanager config.
4. Added mounted/unmounted glyphs to efm2 icons and track state
   code. Now each removable device have "M" glyph on icon if mounted
   and "U" when unmounted.
5. Added mount/unmount/eject commands to icon dropdown menu.
6. Russian translation of mew messages.
7. Other bugfixes and improvements for co-operation.

Now, efm2 contains all code to mount/umnount/eject removable media and
all code to provide corresponding user interface.
It can working independently from 'places' or co-operate with it.

By: Sergey Semernin



SVN revision: 40928
devs/princeamd/enlightenment-0.17-elive
Gustavo Sverzut Barbieri 14 years ago
parent 987192c54d
commit 2af9f44b4f
  1. 407
      data/themes/default.edc
  2. 20
      po/ru.po
  3. 4
      src/bin/e_config.c
  4. 2
      src/bin/e_config.h
  5. 323
      src/bin/e_fm.c
  6. 141
      src/bin/e_fm_hal.c
  7. 4
      src/bin/e_fm_hal.h
  8. 261
      src/bin/e_fm_main.c
  9. 7
      src/bin/e_fm_op.h
  10. 7
      src/bin/e_fm_shared.h
  11. 29
      src/modules/fileman/e_mod_config.c
  12. 24
      src/modules/fileman/e_mod_main.c

@ -13669,6 +13669,9 @@ collections { /* begin the collection of edje groups that are in this file */
image: "icon_efm_dnd_copy.png" COMP;
image: "icon_efm_dnd_ask.png" COMP;
image: "icon_efm_dnd_move.png" COMP;
image: "icon_efm_vol_unmounted.png" COMP;
image: "icon_efm_vol_mounted.png" COMP;
}
parts {
part { name: "label2";
@ -13952,6 +13955,36 @@ collections { /* begin the collection of edje groups that are in this file */
color: 0 0 0 0;
}
}
part { name: "vol_state";
type: IMAGE;
mouse_events: 0;
repeat_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
align: 1.0 1.0;
min: 16 16;
rel1 {
relative: 0.75 0.0;
to: "icon";
}
rel2 {
relative: 1.0 1.0;
to: "icon";
}
}
description { state: "unmounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_unmounted.png";
}
description { state: "mounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_mounted.png";
}
}
part { name: "dnd_action";
type: IMAGE;
mouse_events: 0;
@ -14029,6 +14062,24 @@ collections { /* begin the collection of edje groups that are in this file */
action: STATE_SET "copy" 0.0;
target: "dnd_action";
}
program { name: "vol_off";
signal: "e,state,volume,off";
source: "e";
action: STATE_SET "default" 0.0;
target: "vol_state";
}
program { name: "vol_unmounted";
signal: "e,state,volume,unmounted";
source: "e";
action: STATE_SET "unmounted" 0.0;
target: "vol_state";
}
program { name: "vol_mounted";
signal: "e,state,volume,mounted";
source: "e";
action: STATE_SET "mounted" 0.0;
target: "vol_state";
}
program { name: "thumb_gen";
signal: "e,action,thumb,gen";
source: "e";
@ -14089,6 +14140,9 @@ collections { /* begin the collection of edje groups that are in this file */
image: "icon_efm_dnd_copy.png" COMP;
image: "icon_efm_dnd_ask.png" COMP;
image: "icon_efm_dnd_move.png" COMP;
image: "icon_efm_vol_unmounted.png" COMP;
image: "icon_efm_vol_mounted.png" COMP;
}
parts {
part { name: "label2";
@ -14372,6 +14426,36 @@ collections { /* begin the collection of edje groups that are in this file */
color: 0 0 0 0;
}
}
part { name: "vol_state";
type: IMAGE;
mouse_events: 0;
repeat_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
align: 1.0 1.0;
min: 16 16;
rel1 {
relative: 0.75 0.0;
to: "icon";
}
rel2 {
relative: 1.0 1.0;
to: "icon";
}
}
description { state: "unmounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_unmounted.png";
}
description { state: "mounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_mounted.png";
}
}
part { name: "dnd_action";
type: IMAGE;
mouse_events: 0;
@ -14449,6 +14533,24 @@ collections { /* begin the collection of edje groups that are in this file */
action: STATE_SET "copy" 0.0;
target: "dnd_action";
}
program { name: "vol_off";
signal: "e,state,volume,off";
source: "e";
action: STATE_SET "default" 0.0;
target: "vol_state";
}
program { name: "vol_unmounted";
signal: "e,state,volume,unmounted";
source: "e";
action: STATE_SET "unmounted" 0.0;
target: "vol_state";
}
program { name: "vol_mounted";
signal: "e,state,volume,mounted";
source: "e";
action: STATE_SET "mounted" 0.0;
target: "vol_state";
}
program { name: "thumb_gen";
signal: "e,action,thumb,gen";
source: "e";
@ -14509,6 +14611,9 @@ collections { /* begin the collection of edje groups that are in this file */
image: "icon_efm_dnd_copy.png" COMP;
image: "icon_efm_dnd_ask.png" COMP;
image: "icon_efm_dnd_move.png" COMP;
image: "icon_efm_vol_unmounted.png" COMP;
image: "icon_efm_vol_mounted.png" COMP;
}
parts {
part { name: "bg";
@ -14768,6 +14873,36 @@ collections { /* begin the collection of edje groups that are in this file */
color: 0 0 0 0;
}
}
part { name: "vol_state";
type: IMAGE;
mouse_events: 0;
repeat_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
align: 1.0 1.0;
min: 16 16;
rel1 {
relative: 0.75 0.0;
to: "icon";
}
rel2 {
relative: 1.0 1.0;
to: "icon";
}
}
description { state: "unmounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_unmounted.png";
}
description { state: "mounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_mounted.png";
}
}
part { name: "dnd_action";
type: IMAGE;
mouse_events: 0;
@ -14836,6 +14971,24 @@ collections { /* begin the collection of edje groups that are in this file */
action: STATE_SET "copy" 0.0;
target: "dnd_action";
}
program { name: "vol_off";
signal: "e,state,volume,off";
source: "e";
action: STATE_SET "default" 0.0;
target: "vol_state";
}
program { name: "vol_unmounted";
signal: "e,state,volume,unmounted";
source: "e";
action: STATE_SET "unmounted" 0.0;
target: "vol_state";
}
program { name: "vol_mounted";
signal: "e,state,volume,mounted";
source: "e";
action: STATE_SET "mounted" 0.0;
target: "vol_state";
}
program { name: "thumb_gen";
signal: "e,action,thumb,gen";
source: "e";
@ -14896,6 +15049,9 @@ collections { /* begin the collection of edje groups that are in this file */
image: "icon_efm_dnd_copy.png" COMP;
image: "icon_efm_dnd_ask.png" COMP;
image: "icon_efm_dnd_move.png" COMP;
image: "icon_efm_vol_unmounted.png" COMP;
image: "icon_efm_vol_mounted.png" COMP;
}
parts {
part { name: "bg";
@ -15155,6 +15311,36 @@ collections { /* begin the collection of edje groups that are in this file */
color: 0 0 0 0;
}
}
part { name: "vol_state";
type: IMAGE;
mouse_events: 0;
repeat_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
align: 1.0 1.0;
min: 16 16;
rel1 {
relative: 0.75 0.0;
to: "icon";
}
rel2 {
relative: 1.0 1.0;
to: "icon";
}
}
description { state: "unmounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_unmounted.png";
}
description { state: "mounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_mounted.png";
}
}
part { name: "dnd_action";
type: IMAGE;
mouse_events: 0;
@ -15223,6 +15409,24 @@ collections { /* begin the collection of edje groups that are in this file */
action: STATE_SET "copy" 0.0;
target: "dnd_action";
}
program { name: "vol_off";
signal: "e,state,volume,off";
source: "e";
action: STATE_SET "default" 0.0;
target: "vol_state";
}
program { name: "vol_unmounted";
signal: "e,state,volume,unmounted";
source: "e";
action: STATE_SET "unmounted" 0.0;
target: "vol_state";
}
program { name: "vol_mounted";
signal: "e,state,volume,mounted";
source: "e";
action: STATE_SET "mounted" 0.0;
target: "vol_state";
}
program { name: "thumb_gen";
signal: "e,action,thumb,gen";
source: "e";
@ -15287,6 +15491,9 @@ collections { /* begin the collection of edje groups that are in this file */
image: "icon_efm_dnd_copy.png" COMP;
image: "icon_efm_dnd_ask.png" COMP;
image: "icon_efm_dnd_move.png" COMP;
image: "icon_efm_vol_unmounted.png" COMP;
image: "icon_efm_vol_mounted.png" COMP;
}
parts {
part {
@ -15599,6 +15806,35 @@ collections { /* begin the collection of edje groups that are in this file */
color: 255 255 255 255;
}
}
part { name: "vol_state";
type: IMAGE;
mouse_events: 0;
repeat_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
align: 1.0 1.0;
rel1 {
relative: 0.5 0.0;
to: "icon";
}
rel2 {
relative: 1.0 1.0;
to: "icon";
}
}
description { state: "unmounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_unmounted.png";
}
description { state: "mounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_mounted.png";
}
}
part { name: "dnd_action";
type: IMAGE;
mouse_events: 0;
@ -15695,6 +15931,24 @@ collections { /* begin the collection of edje groups that are in this file */
action: STATE_SET "copy" 0.0;
target: "dnd_action";
}
program { name: "vol_off";
signal: "e,state,volume,off";
source: "e";
action: STATE_SET "default" 0.0;
target: "vol_state";
}
program { name: "vol_unmounted";
signal: "e,state,volume,unmounted";
source: "e";
action: STATE_SET "unmounted" 0.0;
target: "vol_state";
}
program { name: "vol_mounted";
signal: "e,state,volume,mounted";
source: "e";
action: STATE_SET "mounted" 0.0;
target: "vol_state";
}
program { name: "thumb_gen";
signal: "e,action,thumb,gen";
source: "e";
@ -15759,6 +16013,9 @@ collections { /* begin the collection of edje groups that are in this file */
image: "icon_efm_dnd_copy.png" COMP;
image: "icon_efm_dnd_ask.png" COMP;
image: "icon_efm_dnd_move.png" COMP;
image: "icon_efm_vol_unmounted.png" COMP;
image: "icon_efm_vol_mounted.png" COMP;
}
parts {
part {
@ -16071,6 +16328,35 @@ collections { /* begin the collection of edje groups that are in this file */
color: 255 255 255 255;
}
}
part { name: "vol_state";
type: IMAGE;
mouse_events: 0;
repeat_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
align: 1.0 1.0;
rel1 {
relative: 0.5 0.0;
to: "icon";
}
rel2 {
relative: 1.0 1.0;
to: "icon";
}
}
description { state: "unmounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_unmounted.png";
}
description { state: "mounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_mounted.png";
}
}
part { name: "dnd_action";
type: IMAGE;
mouse_events: 0;
@ -16167,6 +16453,24 @@ collections { /* begin the collection of edje groups that are in this file */
action: STATE_SET "copy" 0.0;
target: "dnd_action";
}
program { name: "vol_off";
signal: "e,state,volume,off";
source: "e";
action: STATE_SET "default" 0.0;
target: "vol_state";
}
program { name: "vol_unmounted";
signal: "e,state,volume,unmounted";
source: "e";
action: STATE_SET "unmounted" 0.0;
target: "vol_state";
}
program { name: "vol_mounted";
signal: "e,state,volume,mounted";
source: "e";
action: STATE_SET "mounted" 0.0;
target: "vol_state";
}
program { name: "thumb_gen";
signal: "e,action,thumb,gen";
source: "e";
@ -16232,6 +16536,9 @@ collections { /* begin the collection of edje groups that are in this file */
image: "icon_efm_dnd_copy.png" COMP;
image: "icon_efm_dnd_ask.png" COMP;
image: "icon_efm_dnd_move.png" COMP;
image: "icon_efm_vol_unmounted.png" COMP;
image: "icon_efm_vol_mounted.png" COMP;
}
parts {
part {
@ -16545,6 +16852,35 @@ collections { /* begin the collection of edje groups that are in this file */
color: 255 255 255 255;
}
}
part { name: "vol_state";
type: IMAGE;
mouse_events: 0;
repeat_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
align: 1.0 1.0;
rel1 {
relative: 0.5 0.0;
to: "icon";
}
rel2 {
relative: 1.0 1.0;
to: "icon";
}
}
description { state: "unmounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_unmounted.png";
}
description { state: "mounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_mounted.png";
}
}
part { name: "dnd_action";
type: IMAGE;
mouse_events: 0;
@ -16641,6 +16977,24 @@ collections { /* begin the collection of edje groups that are in this file */
action: STATE_SET "copy" 0.0;
target: "dnd_action";
}
program { name: "vol_off";
signal: "e,state,volume,off";
source: "e";
action: STATE_SET "default" 0.0;
target: "vol_state";
}
program { name: "vol_unmounted";
signal: "e,state,volume,unmounted";
source: "e";
action: STATE_SET "unmounted" 0.0;
target: "vol_state";
}
program { name: "vol_mounted";
signal: "e,state,volume,mounted";
source: "e";
action: STATE_SET "mounted" 0.0;
target: "vol_state";
}
program { name: "thumb_gen";
signal: "e,action,thumb,gen";
source: "e";
@ -16706,6 +17060,9 @@ collections { /* begin the collection of edje groups that are in this file */
image: "icon_efm_dnd_copy.png" COMP;
image: "icon_efm_dnd_ask.png" COMP;
image: "icon_efm_dnd_move.png" COMP;
image: "icon_efm_vol_unmounted.png" COMP;
image: "icon_efm_vol_mounted.png" COMP;
}
parts {
part {
@ -17018,6 +17375,35 @@ collections { /* begin the collection of edje groups that are in this file */
color: 255 255 255 255;
}
}
part { name: "vol_state";
type: IMAGE;
mouse_events: 0;
repeat_events: 0;
description { state: "default" 0.0;
color: 0 0 0 0;
}
description { state: "visible" 0.0;
aspect: 1.0 1.0;
aspect_preference: BOTH;
align: 1.0 1.0;
rel1 {
relative: 0.5 0.0;
to: "icon";
}
rel2 {
relative: 1.0 1.0;
to: "icon";
}
}
description { state: "unmounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_unmounted.png";
}
description { state: "mounted" 0.0;
inherit: "visible" 0.0;
image.normal: "icon_efm_vol_mounted.png";
}
}
part { name: "dnd_action";
type: IMAGE;
mouse_events: 0;
@ -17114,6 +17500,24 @@ collections { /* begin the collection of edje groups that are in this file */
action: STATE_SET "copy" 0.0;
target: "dnd_action";
}
program { name: "vol_off";
signal: "e,state,volume,off";
source: "e";
action: STATE_SET "default" 0.0;
target: "vol_state";
}
program { name: "vol_unmounted";
signal: "e,state,volume,unmounted";
source: "e";
action: STATE_SET "unmounted" 0.0;
target: "vol_state";
}
program { name: "vol_mounted";
signal: "e,state,volume,mounted";
source: "e";
action: STATE_SET "mounted" 0.0;
target: "vol_state";
}
program { name: "thumb_gen";
signal: "e,action,thumb,gen";
source: "e";
@ -23758,6 +24162,9 @@ ICON("computer","icon_efm_root.png", 64) // "fileman/root
ICON("drive-harddisk","icon_efm_hdd.png", 128) // "fileman/hd" "fileman/hdd"
ICON("drive-optical","icon_efm_cd.png", 128) // "fileman/??"
ICON("media-flash","icon_efm_flash.png", 128) // "fileman/??"
ICON("drive-removable-media","icon_efm_usbmedia.png", 128);
ICON("media-eject","icon_efm_eject.png", 64)
/* End of FreeDesktop.Org icons */

@ -7469,3 +7469,23 @@ msgstr "Система"
#~ msgid "Add To Favorites Menu"
#~ msgstr "Добавить в Избранное"
#: ../src/bin/e_fm.c:8045
msgid "Mount"
msgstr "Подключить"
#: ../src/bin/e_fm.c:8040
msgid "Unmount"
msgstr "Отключить"
#: ../src/bin/e_fm.c:8050
msgid "Eject"
msgstr "Извлечь"
#: ../src/modules/fileman/e_mod_config.c:273
msgid "Mount volumes on insert"
msgstr "Монтировать тома при подключении"
#: ../src/modules/fileman/e_mod_config.c:276
msgid "Open filemanager on mount"
msgstr "Открыть менеджер файлов при монтировании"

@ -656,6 +656,8 @@ e_config_init(void)
E_CONFIG_VAL(D, T, thumbscroll_friction, DOUBLE);
E_CONFIG_VAL(D, T, hal_desktop, INT);
E_CONFIG_VAL(D, T, hal_auto_mount, INT);
E_CONFIG_VAL(D, T, hal_auto_open, INT);
E_CONFIG_VAL(D, T, border_keyboard.timeout, DOUBLE);
E_CONFIG_VAL(D, T, border_keyboard.move.dx, UCHAR);
@ -663,8 +665,6 @@ e_config_init(void)
E_CONFIG_VAL(D, T, border_keyboard.resize.dx, UCHAR);
E_CONFIG_VAL(D, T, border_keyboard.resize.dy, UCHAR);
E_CONFIG_VAL(D, T, hal_desktop, INT);
E_CONFIG_VAL(D, T, scale.min, DOUBLE);
E_CONFIG_VAL(D, T, scale.max, DOUBLE);
E_CONFIG_VAL(D, T, scale.factor, DOUBLE);

@ -302,6 +302,8 @@ struct _E_Config
double thumbscroll_friction; // GUI
int hal_desktop;
int hal_auto_mount;
int hal_auto_open;
struct {
double timeout;

@ -359,6 +359,8 @@ static void _e_fm_error_abort_cb(void *data, E_Dialog *dialog);
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);
@ -408,6 +410,15 @@ static int _e_fm2_context_list_sort(const void *data1, const void *data2);
static char *_e_fm_string_append_char(char *str, size_t *size, size_t *len, char c);
static char *_e_fm_string_append_quoted(char *str, size_t *size, size_t *len, const char *src);
void _e_fm2_path_parent_set(Evas_Object *obj, const char *path);
static void _e_fm2_volume_mount(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_fm2_volume_unmount(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_fm2_volume_eject(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_fm2_icon_removable_update(E_Fm2_Icon *ic);
static void _e_fm2_volume_icon_update(E_Volume *v);
static char *_e_fm2_meta_path = NULL;
static Evas_Smart *_e_fm2_smart = NULL;
static Eina_List *_e_fm2_list = NULL;
@ -809,12 +820,31 @@ _e_fm2_cb_mount_fail(void *data)
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;
if (sd->config->view.open_dirs_in_place)
_e_fm2_path_parent_set(data, sd->realpath);
else
evas_object_smart_callback_call(data, "dir_deleted", NULL);
}
}
@ -945,7 +975,7 @@ e_fm2_path_set(Evas_Object *obj, const char *dev, const char *path)
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 +984,7 @@ e_fm2_path_set(Evas_Object *obj, const char *dev, const char *path)
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)
@ -2578,6 +2608,19 @@ _e_fm2_client_unmount(const char *udi)
return _e_fm_client_send_new(E_FM_OP_UNMOUNT, (void *)d, l);
}
EAPI int
_e_fm2_client_eject(const char *udi)
{
char *data;
int size;
size = strlen(udi) + 1;
data = alloca(size);
strcpy(data, udi);
return _e_fm_client_send_new(E_FM_OP_EJECT, data, size);
}
static void
_e_fm2_client_monitor_list_end(Evas_Object *obj)
{
@ -2907,7 +2950,13 @@ e_fm2_client_data(Ecore_Ipc_Event_Client_Data *e)
E_Volume *v;
v = eet_data_descriptor_decode(_e_volume_edd, e->data, e->size);
if (v) e_fm2_hal_volume_add(v);
if (v)
{
e_fm2_hal_volume_add(v);
if (e_config->hal_auto_mount && !v->mounted && !v->first_time)
_e_fm2_client_mount(v->udi, v->mount_point);
v->first_time = 0;
}
}
break;
@ -2932,7 +2981,21 @@ e_fm2_client_data(Ecore_Ipc_Event_Client_Data *e)
udi = e->data;
mountpoint = udi + strlen(udi) + 1;
v = e_fm2_hal_volume_find(udi);
if (v) e_fm2_hal_mount_add(v, mountpoint);
if (v)
{
e_fm2_hal_mount_add(v, mountpoint);
_e_fm2_volume_icon_update(v);
if (e_config->hal_auto_open && !eina_list_count(v->mounts))
{
E_Action *a;
Eina_List *m;
a = e_action_find("fileman");
m = e_manager_list();
if (a && a->func.go && m && m->data)
a->func.go(E_OBJECT(m->data), mountpoint);
}
}
}
break;
@ -2944,15 +3007,62 @@ e_fm2_client_data(Ecore_Ipc_Event_Client_Data *e)
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);
_e_fm2_volume_icon_update(v);
}
}
break;
case E_FM_OP_EJECT_DONE:
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_EJECT_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(_("Eject Error"), _("Can't eject device"), e->data);
}
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);
@ -4601,10 +4711,9 @@ _e_fm2_icon_realize(E_Fm2_Icon *ic)
if ((selectraise) && (!strcmp(selectraise, "on")))
evas_object_stack_below(ic->obj, ic->sd->drop);
}
if (ic->info.removable_full)
edje_object_signal_emit(ic->obj_icon, "e,state,removable,full", "e");
// else
// edje_object_signal_emit(ic->obj_icon, "e,state,removable,empty", "e");
if (ic->info.removable)
_e_fm2_icon_removable_update(ic);
}
static void
@ -7817,6 +7926,7 @@ _e_fm2_icon_menu(E_Fm2_Icon *ic, Evas_Object *obj, unsigned int timestamp)
e_menu_item_callback_set(mi, _e_fm2_new_directory, sd);
}
}
if (!ic->info.removable) {
if (!(sd->icon_menu.flags & E_FM2_MENU_NO_CUT))
{
if (ecore_file_can_write(sd->realpath))
@ -7865,7 +7975,8 @@ _e_fm2_icon_menu(E_Fm2_Icon *ic, Evas_Object *obj, unsigned int timestamp)
e_menu_item_callback_set(mi, _e_fm2_file_symlink_menu, sd);
}
}
}
can_w = 0;
can_w2 = 1;
if (ic->sd->order_file)
@ -7909,7 +8020,7 @@ _e_fm2_icon_menu(E_Fm2_Icon *ic, Evas_Object *obj, unsigned int timestamp)
protect = 0;
sel = eina_list_free(sel);
if ((can_w) && (can_w2) && !(protect))
if ((can_w) && (can_w2) && !(protect) && !ic->info.removable)
{
mi = e_menu_item_new(mn);
e_menu_item_separator_set(mi, 1);
@ -7931,10 +8042,42 @@ _e_fm2_icon_menu(E_Fm2_Icon *ic, Evas_Object *obj, unsigned int timestamp)
}
}
mi = e_menu_item_new(mn);
e_menu_item_label_set(mi, _("Properties"));
e_util_menu_item_theme_icon_set(mi, "document-properties");
e_menu_item_callback_set(mi, _e_fm2_file_properties, ic);
if (ic->info.removable)
{
E_Volume *v;
v = e_fm2_hal_volume_find(ic->info.link);
if (v)
{
mi = e_menu_item_new(mn);
e_menu_item_separator_set(mi, 1);
mi = e_menu_item_new(mn);
if (v->mounted)
{
e_menu_item_label_set(mi, _("Unmount"));
e_menu_item_callback_set(mi, _e_fm2_volume_unmount, v);
}
else
{
e_menu_item_label_set(mi, _("Mount"));
e_menu_item_callback_set(mi, _e_fm2_volume_mount, v);
}
mi = e_menu_item_new(mn);
e_menu_item_label_set(mi, _("Eject"));
e_util_menu_item_theme_icon_set(mi, "media-eject");
e_menu_item_callback_set(mi, _e_fm2_volume_eject, v);
mi = e_menu_item_new(mn);
e_menu_item_separator_set(mi, 1);
}
}
mi = e_menu_item_new(mn);
e_menu_item_label_set(mi, _("Properties"));
e_util_menu_item_theme_icon_set(mi, "document-properties");
e_menu_item_callback_set(mi, _e_fm2_file_properties, ic);
if (ic->info.mime)
{
@ -9001,6 +9144,37 @@ _e_fm_error_ignore_all_cb(void *data, E_Dialog *dialog)
e_object_del(E_OBJECT(dialog));
}
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)
{
@ -9369,10 +9543,7 @@ _e_fm2_live_process(Evas_Object *obj)
ic->removable_state_change = 0;
if ((ic->realized) && (ic->obj_icon))
{
if (ic->info.removable_full)
edje_object_signal_emit(ic->obj_icon, "e,state,removable,full", "e");
else
edje_object_signal_emit(ic->obj_icon, "e,state,removable,empty", "e");
_e_fm2_icon_removable_update(ic);
_e_fm2_icon_label_set(ic, ic->obj);
}
}
@ -9510,3 +9681,101 @@ _e_fm2_theme_edje_icon_object_set(E_Fm2_Smart_Data *sd, Evas_Object *o, const ch
ret = e_theme_edje_object_set(o, category, buf);
return ret;
}
static void
_e_fm2_volume_mount(void *data, E_Menu *m, E_Menu_Item *mi)
{
E_Volume *v;
char *mp;
v = data;
if (!v) return;
mp = e_fm2_hal_volume_mountpoint_get(v);
_e_fm2_client_mount(v->udi, mp);
free(mp);
}
static void
_e_fm2_volume_unmount(void *data, E_Menu *m, E_Menu_Item *mi)
{
E_Volume *v;
v = data;
if (!v) return;
v->auto_unmount = 0;
_e_fm2_client_unmount(v->udi);
}
static void
_e_fm2_volume_eject(void *data, E_Menu *m, E_Menu_Item *mi)
{
E_Volume *v;
v = data;
if (!v) return;
v->auto_unmount = 0;
_e_fm2_client_eject(v->udi);
}
static void
_update_volume_icon(E_Volume *v, E_Fm2_Icon *ic)
{
if (ic->info.removable_full)
edje_object_signal_emit(ic->obj_icon, "e,state,removable,full", "e");
else
edje_object_signal_emit(ic->obj_icon, "e,state,removable,empty", "e");
if (v)
{
if (v->mounted)
edje_object_signal_emit(ic->obj, "e,state,volume,mounted", "e");
else
edje_object_signal_emit(ic->obj, "e,state,volume,unmounted", "e");
}
else
edje_object_signal_emit(ic->obj, "e,state,volume,off", "e");
}
static void
_e_fm2_volume_icon_update(E_Volume *v)
{
Evas_Object *o;
char file[PATH_MAX], fav[PATH_MAX], desk[PATH_MAX];
Eina_List *l;
E_Fm2_Icon *ic;
if (!v || !v->storage) return;
e_user_dir_snprintf(fav, sizeof(fav), "fileman/favorites");
e_user_homedir_snprintf(desk, sizeof(desk), "Desktop");
snprintf(file, sizeof(file), "|%s_%d.desktop",
ecore_file_file_get(v->storage->udi), v->partition_number);
EINA_LIST_FOREACH(_e_fm2_list, l, o)
{
const char *rp;
if ((_e_fm2_list_walking > 0) &&
(eina_list_data_find(_e_fm2_list_remove, o))) continue;
rp = e_fm2_real_path_get(o);
if (strcmp(rp, fav) && strcmp(rp, desk)) continue;
ic = _e_fm2_icon_find(l->data, file);
if (ic)
_update_volume_icon(v, ic);
}
}
static void
_e_fm2_icon_removable_update(E_Fm2_Icon *ic)
{
E_Volume *v;
if (!ic) return;
v = e_fm2_hal_volume_find(ic->info.link);
_update_volume_icon(v, ic);
}

@ -9,8 +9,11 @@
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 +271,20 @@ e_fm2_hal_volume_add(E_Volume *v)
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);
}
@ -403,7 +415,12 @@ e_fm2_hal_mount_add(E_Volume *v, const char *mountpoint)
Eina_List *l;
v->mounted = 1;
v->mount_point = strdup(mountpoint);
if (mountpoint && (*mountpoint != 0))
{
if (v->mount_point)
free(v->mount_point);
v->mount_point = strdup(mountpoint);
}
for (l = v->mounts; l; l = l->next)
_e_fm2_hal_mount_ok(l->data);
@ -412,18 +429,34 @@ e_fm2_hal_mount_add(E_Volume *v, const char *mountpoint)
}
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);
if (m->mount_point) eina_stringshare_del(m->mount_point);
if (m->timeout)
{
ecore_timer_del(m->timeout);
m->timeout = NULL;
}
free(m);
}
@ -469,16 +502,42 @@ e_fm2_hal_mount(E_Volume *v,
v->mounts = eina_list_prepend(v->mounts, m);
// printf("BEGIN MOUNT %p '%s'\n", m, v->mount_point);
if (!v->mounted)
{
if (m->timeout) ecore_timer_del(m->timeout);
m->timeout = ecore_timer_add(10.0, (int (*)(void*))_e_fm2_hal_mount_timeout, m);
v->auto_unmount = 1;
_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)
{
@ -486,32 +545,66 @@ e_fm2_hal_unmount(E_Fm2_Mount *m)
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)
{
m->mounted = 1;
if (m->volume) m->mount_point = eina_stringshare_add(m->volume->mount_point);
if (m->timeout)
if (m->volume)
m->mount_point = eina_stringshare_add(m->volume->mount_point);
if (m->mount_ok)
m->mount_ok(m->data);
// 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)
{
ecore_timer_del(m->timeout);
m->timeout = NULL;
eina_stringshare_del(m->mount_point);
m->mount_point = NULL;
}
if (m->mount_ok) m->mount_ok(m->data);
// printf("MOUNT OK '%s'\n", m->mount_point);
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->unmount_ok)
m->unmount_ok(m->data);
}
static int
_e_fm2_hal_mount_timeout(E_Fm2_Mount *m)
static void
_e_fm2_hal_unmount_fail(E_Fm2_Mount *m)
{
m->mount_fail(m->data);
m->timeout = NULL;
return 0;
m->mounted = 1;
if (m->unmount_fail)
m->unmount_fail(m->data);
}
EAPI void

@ -17,13 +17,15 @@ EAPI E_Volume *e_fm2_hal_volume_find(const char *udi);
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);

@ -58,6 +58,10 @@
#define DEF_ROUND_TRIP_TOLERANCE 0.01
#define DEF_MOD_BACKOFF 0.2
#define E_FM_MOUNT_TIMEOUT 30.0
#define E_FM_UNMOUNT_TIMEOUT 60.0
#define E_FM_EJECT_TIMEOUT 15.0
typedef struct _E_Dir E_Dir;
typedef struct _E_Fop E_Fop;
typedef struct _E_Mod E_Mod;
@ -189,17 +193,26 @@ static void _e_dbus_cb_vol_prop(void *data, void *reply_data, DBusError *error);
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 void _e_dbus_cb_vol_unmounted_before_eject(void *user_data, void *method_return, DBusError *error);
static int _e_dbus_vb_vol_ejecting_after_unmount(void *data);
static void _e_dbus_cb_vol_ejected(void *user_data, void *method_return, DBusError *error);
static int _e_dbus_format_error_msg(char **buf, E_Volume *v, DBusError *error);
static int _e_dbus_vol_mount_timeout(void *data);
static int _e_dbus_vol_unmount_timeout(void *data);
static int _e_dbus_vol_eject_timeout(void *data);
EAPI E_Storage *e_storage_add(const char *udi);
EAPI void e_storage_del(const char *udi);