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
This commit is contained in:
Gustavo Sverzut Barbieri 2009-06-07 00:00:41 +00:00
parent 987192c54d
commit 2af9f44b4f
12 changed files with 1136 additions and 95 deletions

View File

@ -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 */

View File

@ -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 "Открыть менеджер файлов при монтировании"

View File

@ -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);

View File

@ -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;

View File

@ -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,11 +820,30 @@ _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;
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;
@ -2946,13 +3009,60 @@ e_fm2_client_data(Ecore_Ipc_Event_Client_Data *e)
v = e_fm2_hal_volume_find(udi);
if (v)
{
v->mounted = 0;
if (v->mount_point) free(v->mount_point);
v->mount_point = NULL;
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,6 +7975,7 @@ _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;
@ -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,6 +8042,38 @@ _e_fm2_icon_menu(E_Fm2_Icon *ic, Evas_Object *obj, unsigned int timestamp)
}
}
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");
@ -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);
}

View File

@ -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;
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);
}
@ -472,13 +505,39 @@ e_fm2_hal_mount(E_Volume *v,
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)
{
ecore_timer_del(m->timeout);
m->timeout = NULL;
}
if (m->mount_ok) m->mount_ok(m->data);
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 int
_e_fm2_hal_mount_timeout(E_Fm2_Mount *m)
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->mount_fail)
m->mount_fail(m->data);
m->timeout = NULL;
return 0;
}
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 void
_e_fm2_hal_unmount_fail(E_Fm2_Mount *m)
{
m->mounted = 1;
if (m->unmount_fail)
m->unmount_fail(m->data);
}
EAPI void

View File

@ -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);

View File

@ -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);
EAPI E_Storage *e_storage_find(const char *udi);
EAPI E_Volume *e_volume_add(const char *udi);
EAPI E_Volume *e_volume_add(const char *udi, char first_time);
EAPI void e_volume_del(const char *udi);
EAPI E_Volume *e_volume_find(const char *udi);
EAPI void e_volume_mount(E_Volume *v);
EAPI void e_volume_unmount(E_Volume *v);
EAPI void e_volume_eject(E_Volume *v);
/* local subsystem globals */
static Ecore_Ipc_Server *_e_ipc_server = NULL;
@ -366,7 +379,7 @@ _e_dbus_cb_dev_vol(void *user_data, void *reply_data, DBusError *error)
EINA_LIST_FOREACH(ret->strings, l, device)
{
// printf("DB VOL+: %s\n", device);
e_volume_add(device);
e_volume_add(device, 1);
}
}
@ -407,7 +420,7 @@ _e_dbus_cb_vol_is(void *user_data, void *reply_data, DBusError *error)
if (ret && ret->boolean)
{
// printf("DB VOL IS+: %s\n", udi);
e_volume_add(udi);
e_volume_add(udi, 0);
}
error:
@ -720,6 +733,26 @@ _e_dbus_cb_vol_prop(void *data, void *reply_data, DBusError *error)
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 +763,18 @@ _e_dbus_cb_vol_prop_mount_modified(void *data, void *reply_data, DBusError *erro
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;
}
@ -767,7 +811,7 @@ _e_dbus_cb_vol_prop_mount_modified(void *data, void *reply_data, DBusError *erro
static Eina_List *_e_vols = NULL;
EAPI E_Volume *
e_volume_add(const char *udi)
e_volume_add(const char *udi, char first_time)
{
E_Volume *v;
@ -778,6 +822,7 @@ e_volume_add(const char *udi)
// printf("VOL+ %s\n", udi);
v->udi = strdup(udi);
v->icon = NULL;
v->first_time = first_time;
_e_vols = eina_list_append(_e_vols, v);
e_hal_device_get_all_properties(_e_dbus_conn, v->udi,
_e_dbus_cb_vol_prop, v);
@ -785,6 +830,7 @@ e_volume_add(const char *udi)
udi,
"org.freedesktop.Hal.Device",
"PropertyModified", _e_dbus_cb_prop_modified, v);
v->guard = NULL;
return v;
}
@ -796,6 +842,11 @@ e_volume_del(const char *udi)
v = e_volume_find(udi);
if (!v) return;
if (v->guard)
{
ecore_timer_del(v->guard);
v->guard = NULL;
}
if (v->prop_handler) e_dbus_signal_handler_del(_e_dbus_conn, v->prop_handler);
if (v->validated)
{
@ -825,6 +876,26 @@ e_volume_find(const char *udi)
return NULL;
}
static int
_e_dbus_vol_mount_timeout(void *data)
{
E_Volume *v = data;
DBusError error;
char *buf;
int size;
v->guard = NULL;
dbus_pending_call_cancel(v->op);
error.name = "org.enlightenment.fm2.MountTimeout";
error.message = "Unable to mount the volume with specified time-out.";
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);
free(buf);
return 0;
}
static void
_e_dbus_cb_vol_mounted(void *user_data, void *method_return, DBusError *error)
{
@ -832,11 +903,23 @@ _e_dbus_cb_vol_mounted(void *user_data, void *method_return, DBusError *error)
char *buf;
int size;
if (v->guard)
{
ecore_timer_del(v->guard);
v->guard = NULL;
}
if (dbus_error_is_set(error))
{
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;
@ -844,9 +927,10 @@ _e_dbus_cb_vol_mounted(void *user_data, void *method_return, DBusError *error)
strcpy(buf, v->udi);
strcpy(buf + strlen(buf) + 1, v->mount_point);
ecore_ipc_server_send(_e_ipc_server,
6/*E_IPC_DOMAIN_FM*/,
6/*E_IPC_DOMAIN_FM*//*,
E_FM_OP_MOUNT_DONE,
0, 0, 0, buf, size);
*/
}
EAPI void
@ -856,7 +940,7 @@ e_volume_mount(E_Volume *v)
char *mount_point;
Eina_List *opt = NULL;
if (!v || !v->mount_point || strncmp(v->mount_point, "/media/", 7))
if (!v || v->guard || !v->mount_point || strncmp(v->mount_point, "/media/", 7))
return;
mount_point = v->mount_point + 7;
@ -869,11 +953,32 @@ e_volume_mount(E_Volume *v)
snprintf(buf, sizeof(buf), "uid=%i", (int)getuid());
opt = eina_list_append(opt, buf);
}
e_hal_device_volume_mount(_e_dbus_conn, v->udi, mount_point,
v->fstype, opt, NULL, v);
v->guard = ecore_timer_add(E_FM_MOUNT_TIMEOUT, _e_dbus_vol_mount_timeout, v);
v->op = e_hal_device_volume_mount(_e_dbus_conn, v->udi, mount_point,
v->fstype, opt, _e_dbus_cb_vol_mounted, v);
opt = eina_list_free(opt);
}
static int
_e_dbus_vol_unmount_timeout(void *data)
{
E_Volume *v = data;
DBusError error;
char *buf;
int size;
v->guard = NULL;
dbus_pending_call_cancel(v->op);
error.name = "org.enlightenment.fm2.UnmountTimeout";
error.message = "Unable to unmount the volume with specified time-out.";
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);
free(buf);
return 0;
}
static void
_e_dbus_cb_vol_unmounted(void *user_data, void *method_return, DBusError *error)
{
@ -881,11 +986,23 @@ _e_dbus_cb_vol_unmounted(void *user_data, void *method_return, DBusError *error)
char *buf;
int size;
if (v->guard)
{
ecore_timer_del(v->guard);
v->guard = NULL;
}
if (dbus_error_is_set(error))
{
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;
@ -893,19 +1010,120 @@ _e_dbus_cb_vol_unmounted(void *user_data, void *method_return, DBusError *error)
strcpy(buf, v->udi);
strcpy(buf + strlen(buf) + 1, v->mount_point);
ecore_ipc_server_send(_e_ipc_server,
6/*E_IPC_DOMAIN_FM*/,
6/*E_IPC_DOMAIN_FM*//*,
E_FM_OP_UNMOUNT_DONE,
0, 0, 0, buf, size);
*/
}
EAPI void
e_volume_unmount(E_Volume *v)
{
// printf("unmount %s %s\n", v->udi, v->mount_point);
e_hal_device_volume_unmount(_e_dbus_conn, v->udi, NULL,
if (!v || v->guard) return;
v->guard = ecore_timer_add(E_FM_UNMOUNT_TIMEOUT, _e_dbus_vol_unmount_timeout, v);
v->op = e_hal_device_volume_unmount(_e_dbus_conn, v->udi, NULL,
_e_dbus_cb_vol_unmounted, v);
}
static int
_e_dbus_vol_eject_timeout(void *data)
{
E_Volume *v = data;
DBusError error;
char *buf;
int size;
v->guard = NULL;
dbus_pending_call_cancel(v->op);
error.name = "org.enlightenment.fm2.EjectTimeout";
error.message = "Unable to eject the media with specified time-out.";
size = _e_dbus_format_error_msg(&buf, v, &error);
ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_EJECT_ERROR,
0, 0, 0, buf, size);
free(buf);
return 0;
}
static int
_e_dbus_vb_vol_ejecting_after_unmount(void *data)
{
E_Volume *v = data;
v->guard = ecore_timer_add(E_FM_EJECT_TIMEOUT, _e_dbus_vol_eject_timeout, v);
v->op = e_hal_device_volume_eject(_e_dbus_conn, v->udi, NULL,
_e_dbus_cb_vol_ejected, v);
return 0;
}
static void
_e_dbus_cb_vol_unmounted_before_eject(void *user_data, void *method_return, DBusError *error)
{
E_Volume *v = user_data;
char err;
err = dbus_error_is_set(error) ? 1 : 0;
_e_dbus_cb_vol_unmounted(user_data, method_return, error);
// delay is required for all message handlers were executed after unmount
if (!err)
ecore_timer_add(1.0, _e_dbus_vb_vol_ejecting_after_unmount, v);
}
static void
_e_dbus_cb_vol_ejected(void *user_data, void *method_return, DBusError *error)
{
E_Volume *v = user_data;
char *buf;
int size;
if (v->guard)
{
ecore_timer_del(v->guard);
v->guard = NULL;
}
if (dbus_error_is_set(error))
{
size = _e_dbus_format_error_msg(&buf, v, error);
ecore_ipc_server_send(_e_ipc_server, 6/*E_IPC_DOMAIN_FM*/, E_FM_OP_EJECT_ERROR,
0, 0, 0, buf, size);
dbus_error_free(error);
free(buf);
return;
}
size = strlen(v->udi) + 1;
buf = alloca(size);
strcpy(buf, v->udi);
ecore_ipc_server_send(_e_ipc_server,
6/*E_IPC_DOMAIN_FM*/,
E_FM_OP_EJECT_DONE,
0, 0, 0, buf, size);
}
EAPI void
e_volume_eject(E_Volume *v)
{
if (!v || v->guard) return;
if (v->mounted)
{
v->guard = ecore_timer_add(E_FM_UNMOUNT_TIMEOUT, _e_dbus_vol_unmount_timeout, v);
v->op = e_hal_device_volume_unmount(_e_dbus_conn, v->udi, NULL,
_e_dbus_cb_vol_unmounted_before_eject, v);
}
else
{
v->guard = ecore_timer_add(E_FM_EJECT_TIMEOUT, _e_dbus_vol_eject_timeout, v);
v->op = e_hal_device_volume_eject(_e_dbus_conn, v->udi, NULL,
_e_dbus_cb_vol_ejected, v);
}
}
/* local subsystem functions */
static int
_e_ipc_init(void)
@ -1376,6 +1594,17 @@ _e_ipc_cb_server_data(void *data, int type, void *event)
}
}
break;
case E_FM_OP_EJECT:/* eject udi */
{
E_Volume *v;
const char *udi;
udi = e->data;
v = e_volume_find(udi);
if (v)
e_volume_eject(v);
}
break;
case E_FM_OP_QUIT: /* quit */
ecore_main_loop_quit();
break;

View File

@ -47,7 +47,12 @@ typedef enum _E_Fm_Op_Type
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_EJECT,
E_FM_OP_EJECT_DONE,
E_FM_OP_EJECT_ERROR
} E_Fm_Op_Type;
#else

View File

@ -58,6 +58,11 @@ struct _E_Volume
Eina_List *mounts;
unsigned char validated;
char auto_unmount; // unmount, when last associated fm window closed
char first_time; // volume discovery in init sequence
Ecore_Timer *guard; // operation guard timer
DBusPendingCall *op; // d-bus call handle
};
struct _E_Fm2_Mount
@ -65,7 +70,6 @@ struct _E_Fm2_Mount
const char *udi;
const char *mount_point;
Ecore_Timer *timeout;
void (*mount_ok) (void *data);
void (*mount_fail) (void *data);
void (*unmount_ok) (void *data);
@ -161,6 +165,7 @@ _e_volume_edd_new(void)
DAT("mounted", mounted, EET_T_CHAR);
DAT("mount_point", mount_point, EET_T_STRING);
DAT("parent", parent, EET_T_STRING);
DAT("first_time", first_time, EET_T_CHAR);
#undef DAT
return edd;
}

View File

@ -65,6 +65,8 @@ struct _E_Config_Dialog_Data
struct
{
int desktop;
int auto_mount;
int auto_open;
} hal;
E_Config_Dialog *cfd;
@ -124,6 +126,8 @@ _fill_data(E_Config_Dialog_Data *cfdata)
cfdata->list.sort.dirs.first = fileman_config->list.sort.dirs.first;
cfdata->list.sort.case_sen = !(fileman_config->list.sort.no_case);
cfdata->hal.desktop = e_config->hal_desktop;
cfdata->hal.auto_mount = e_config->hal_auto_mount;
cfdata->hal.auto_open = e_config->hal_auto_open;
}
static void
@ -160,6 +164,9 @@ _basic_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
else
e_fm2_hal_hide_desktop_icons();
e_config->hal_auto_mount = cfdata->hal.auto_mount;
e_config->hal_auto_open = cfdata->hal.auto_open;
e_config_save_queue();
/* FIXME: reload/refresh existing fm's */
@ -184,7 +191,9 @@ _basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
(fileman_config->list.sort.dirs.first != cfdata->list.sort.dirs.first) ||
(fileman_config->list.sort.dirs.last != !(cfdata->list.sort.dirs.first)) ||
(fileman_config->list.sort.no_case != !(cfdata->list.sort.case_sen)) ||
(e_config->hal_desktop != cfdata->hal.desktop));
(e_config->hal_desktop != cfdata->hal.desktop) ||
(e_config->hal_auto_mount != cfdata->hal.auto_mount) ||
(e_config->hal_auto_open != cfdata->hal.auto_open));
}
static Evas_Object *
@ -254,11 +263,21 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
ob = e_widget_check_add(evas, _("Show Toolbar"),
&(cfdata->view.show_toolbar));
e_widget_list_object_append(o, ob, 1, 1, 0.5);
e_widget_toolbook_page_append(otb, NULL, _("Behavior"), o, 0, 0, 0, 0, 0.5, 0.0);
o = e_widget_list_add(evas, 2, 0);
ob = e_widget_check_add(evas, _("Show HAL icons on desktop"),
&(cfdata->hal.desktop));
e_widget_list_object_append(o, ob, 1, 1, 0.5);
ob = e_widget_check_add(evas, _("Mount volumes on insert"),
&(cfdata->hal.auto_mount));
e_widget_list_object_append(o, ob, 1, 1, 0.5);
ob = e_widget_check_add(evas, _("Open filemanager on mount"),
&(cfdata->hal.auto_open));
e_widget_list_object_append(o, ob, 1, 1, 0.5);
e_widget_toolbook_page_append(otb, NULL, _("Behavior"), o, 0, 0, 0, 0, 0.5, 0.0);
e_widget_toolbook_page_append(otb, NULL, _("HAL"), o, 0, 0, 0, 0, 0.5, 0.0);
e_widget_toolbook_page_show(otb, 0);
return otb;

View File

@ -215,21 +215,6 @@ _e_mod_action_fileman_cb(E_Object *obj, const char *params)
//~ ecore_idle_enterer_add(_e_mod_fileman_defer_cb, m->zone);
//~ }
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)
{
@ -253,8 +238,13 @@ _e_mod_menu_volume_cb(void *data, E_Menu *m, E_Menu_Item *mi)
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