From 5abb426d3687915cda630aaeeb2b2a44432f5b32 Mon Sep 17 00:00:00 2001 From: Davide Andreoli Date: Wed, 1 May 2013 21:43:11 +0000 Subject: [PATCH] Places: rename edbus to eldbus SVN revision: 84544 --- configure.ac | 30 +-- src/Makefile.am | 4 +- src/e_mod_places.c | 12 +- src/e_mod_udisks_edbus2.c | 417 -------------------------------------- src/e_mod_udisks_edbus2.h | 8 - src/e_mod_udisks_eldbus.c | 417 ++++++++++++++++++++++++++++++++++++++ src/e_mod_udisks_eldbus.h | 8 + 7 files changed, 448 insertions(+), 448 deletions(-) delete mode 100644 src/e_mod_udisks_edbus2.c delete mode 100644 src/e_mod_udisks_edbus2.h create mode 100644 src/e_mod_udisks_eldbus.c create mode 100644 src/e_mod_udisks_eldbus.h diff --git a/configure.ac b/configure.ac index a5d2c21..2593a83 100644 --- a/configure.ac +++ b/configure.ac @@ -70,15 +70,15 @@ if test "x$want_udisks" = "xno";then have_udisks=no fi -# check for edbus v2 (default enabled) -PKG_CHECK_MODULES([EDBUS2], [edbus2 >= 1.7.99], - [have_edbus2="yes"], [have_edbus2="no"]) -want_edbus2=yes -AC_ARG_ENABLE([edbus2], - AS_HELP_STRING([--enable-edbus2],[enable UDisks with edbus2 support @<:@default=enabled@:>@]), - [want_edbus2=$enableval]) -if test "x$want_edbus2" = "xno";then - have_edbus2=no +# check for eldbus v2 (default enabled) +PKG_CHECK_MODULES([ELDBUS], [eldbus >= 1.7.99], + [have_eldbus="yes"], [have_eldbus="no"]) +want_eldbus=yes +AC_ARG_ENABLE([eldbus], + AS_HELP_STRING([--enable-eldbus],[enable UDisks with eldbus support @<:@default=enabled@:>@]), + [want_eldbus=$enableval]) +if test "x$want_eldbus" = "xno";then + have_eldbus=no fi # check for eeze (default disabled) @@ -93,12 +93,12 @@ if test "x$want_eeze" != "xyes";then fi # do not use both e_dbus and eldbus -if test "x$have_edbus2" = "xyes";then +if test "x$have_eldbus" = "xyes";then have_udisks=no fi -AM_CONDITIONAL([HAVE_EDBUS2], [test "x$have_edbus2" = "xyes"]) -test "x$have_edbus2" = "xyes" && AC_DEFINE_UNQUOTED([HAVE_EDBUS2], [1], [enable edbus2 support]) +AM_CONDITIONAL([HAVE_ELDBUS], [test "x$have_eldbus" = "xyes"]) +test "x$have_eldbus" = "xyes" && AC_DEFINE_UNQUOTED([HAVE_ELDBUS], [1], [enable eldbus support]) AM_CONDITIONAL([HAVE_UDISKS], [test "x$have_udisks" = "xyes"]) test "x$have_udisks" = "xyes" && AC_DEFINE_UNQUOTED([HAVE_UDISKS], [1], [enable Udisks support]) @@ -141,8 +141,8 @@ SUMMARY_EOF echo cat << DEVICE_EOF Device Backends: - * build udisks (e_dbus v1)....: $have_udisks (deprecated) - * build udisks (edbus v2)....: $have_edbus2 (suggested) - * build eeze..................: $have_eeze (experimental) + * build udisks (e_dbus)....: $have_udisks (deprecated) + * build udisks (eldbus)....: $have_eldbus (suggested) + * build eeze...............: $have_eeze (experimental) DEVICE_EOF echo diff --git a/src/Makefile.am b/src/Makefile.am index c61ce7e..7e202d4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,8 +14,8 @@ module_la_SOURCES = e_mod_main.h \ e_mod_places.c \ e_mod_udisks.h \ e_mod_udisks.c \ - e_mod_udisks_edbus2.h \ - e_mod_udisks_edbus2.c \ + e_mod_udisks_eldbus.h \ + e_mod_udisks_eldbus.c \ e_mod_eeze.h \ e_mod_eeze.c diff --git a/src/e_mod_places.c b/src/e_mod_places.c index 0aacafc..55dcbd3 100644 --- a/src/e_mod_places.c +++ b/src/e_mod_places.c @@ -11,8 +11,8 @@ #ifdef HAVE_EEZE # include "e_mod_eeze.h" #endif -#ifdef HAVE_EDBUS2 -# include "e_mod_udisks_edbus2.h" +#ifdef HAVE_ELDBUS +# include "e_mod_udisks_eldbus.h" #endif /* Local Function Prototypes */ @@ -47,8 +47,8 @@ places_init(void) #ifdef HAVE_EEZE places_eeze_init(); #endif -#ifdef HAVE_EDBUS2 - places_udisks_edbus2_init(); +#ifdef HAVE_ELDBUS + places_udisks_eldbus_init(); #endif snprintf(theme_file, PATH_MAX, "%s/e-module-places.edj", @@ -70,8 +70,8 @@ places_shutdown(void) #ifdef HAVE_EEZE places_eeze_shutdown(); #endif -#ifdef HAVE_EDBUS2 - places_udisks_edbus2_shutdown(); +#ifdef HAVE_ELDBUS + places_udisks_eldbus_shutdown(); #endif } diff --git a/src/e_mod_udisks_edbus2.c b/src/e_mod_udisks_edbus2.c deleted file mode 100644 index 62fdb40..0000000 --- a/src/e_mod_udisks_edbus2.c +++ /dev/null @@ -1,417 +0,0 @@ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_EDBUS2 - -#include -#include -#include "e_mod_places.h" - - -/* Local Function Prototypes */ -static void _places_udisks_name_start(void *data, const EDBus_Message *msg, EDBus_Pending *pending); -static void _places_udisks_enumerate_devices_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending); -static void _places_udisks_device_add_cb(void *data, const EDBus_Message *msg); -static void _places_udisks_device_del_cb(void *data, const EDBus_Message *msg); -static void _places_udisks_device_changed_cb(void *data, const EDBus_Message *msg); -static void _places_udisks_vol_props_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending); - -static Volume* _places_udisks_volume_add(const char *devpath, Eina_Bool first_time); -static void _places_udisks_mount_func(Volume *vol, Eina_List *opts); -static void _places_udisks_unmount_func(Volume *vol, Eina_List *opts); -static void _places_udisks_eject_func(Volume *vol, Eina_List *opts); -static void _places_udisks_free_func(Volume *vol); - - -/* Local Variables */ -#define UDISKS_BUS "org.freedesktop.UDisks" -#define UDISKS_PATH "/org/freedesktop/UDisks" -#define UDISKS_IFACE "org.freedesktop.UDisks" -#define UDISKS_DEVICE_IFACE "org.freedesktop.UDisks.Device" - -static EDBus_Connection *_places_dbus_conn = NULL; -static EDBus_Proxy *_places_udisks_proxy = NULL; - - -/* API */ -Eina_Bool -places_udisks_edbus2_init(void) -{ - printf("PLACES: udisks2: init()\n"); - - if (!edbus_init()) - return EINA_FALSE; - - _places_dbus_conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SYSTEM); - if (!_places_dbus_conn) - { - printf("PLACES: udisks2: Error connecting to system bus. Is it running?\n"); - return EINA_FALSE; - } - - edbus_name_start(_places_dbus_conn, UDISKS_BUS, 0, - _places_udisks_name_start, NULL); - - return EINA_TRUE; -} - -void -places_udisks_edbus2_shutdown(void) -{ - if (_places_udisks_proxy) edbus_proxy_unref(_places_udisks_proxy); - if (_places_dbus_conn) edbus_connection_unref(_places_dbus_conn); - edbus_shutdown(); -} - -/* Implementation */ -static void -_places_udisks_name_start(void *data, const EDBus_Message *msg, - EDBus_Pending *pending) -{ - EDBus_Object *obj; - unsigned flag; - - EINA_SAFETY_ON_FALSE_RETURN(edbus_message_arguments_get(msg, "u", &flag)); - - obj = edbus_object_get(_places_dbus_conn, UDISKS_BUS, UDISKS_PATH); - _places_udisks_proxy = edbus_proxy_get(obj, UDISKS_IFACE); - - edbus_proxy_call(_places_udisks_proxy, "EnumerateDevices", - _places_udisks_enumerate_devices_cb, NULL, -1, ""); - - edbus_proxy_signal_handler_add(_places_udisks_proxy, "DeviceAdded", - _places_udisks_device_add_cb, NULL); - edbus_proxy_signal_handler_add(_places_udisks_proxy, "DeviceRemoved", - _places_udisks_device_del_cb, NULL); -} - -static Volume* -_places_udisks_volume_add(const char *devpath, Eina_Bool first_time) -{ - EDBus_Object *obj; - EDBus_Proxy *proxy; - Volume *vol; - - // create the EDBus object and proxy - obj = edbus_object_get(_places_dbus_conn, UDISKS_BUS, devpath); - if (!obj) return NULL; - proxy = edbus_proxy_get(obj, UDISKS_DEVICE_IFACE); - if (!proxy) return NULL; - - // create the places volume - vol = places_volume_add(devpath, first_time); - if (!vol) return NULL; - vol->backend_data = proxy; - vol->mount_func = _places_udisks_mount_func; - vol->unmount_func = _places_udisks_unmount_func; - vol->eject_func = _places_udisks_eject_func; - vol->free_func = _places_udisks_free_func; - - // get notification when the dive change - edbus_proxy_signal_handler_add(proxy, "Changed", - _places_udisks_device_changed_cb, vol); - - return vol; -} - -/* Callback of UDisks method "EnumerateDevices()" */ -static void -_places_udisks_enumerate_devices_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending) -{ - EDBus_Message_Iter *ao; - const char *devpath; - - EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); - EINA_SAFETY_ON_FALSE_RETURN(edbus_message_arguments_get(msg, "ao", &ao)); - - while (edbus_message_iter_get_and_next(ao, 'o', &devpath)) - { - Volume *vol; - vol = _places_udisks_volume_add(devpath, EINA_TRUE); - if (!vol) return; - edbus_proxy_property_get_all((EDBus_Proxy *)vol->backend_data, - _places_udisks_vol_props_cb, vol); - } -} - -/* Callback for UDisks signal "DeviceAdded" */ -static void -_places_udisks_device_add_cb(void *data, const EDBus_Message *msg) -{ - Volume *vol; - char *devpath; - - EINA_SAFETY_ON_FALSE_RETURN(edbus_message_arguments_get(msg, "o", &devpath)); - printf("PLACES udisks: DeviceAdded [%s]\n", devpath); - - if ((vol = _places_udisks_volume_add(devpath, EINA_FALSE))) - edbus_proxy_property_get_all((EDBus_Proxy *)vol->backend_data, - _places_udisks_vol_props_cb, vol); -} - -/* Callback for UDisks signal "DeviceRemoved" */ -static void -_places_udisks_device_del_cb(void *data, const EDBus_Message *msg) -{ - Volume *vol; - char *devpath; - - EINA_SAFETY_ON_FALSE_RETURN(edbus_message_arguments_get(msg, "o", &devpath)); - - if ((vol = places_volume_by_id_get(devpath))) - places_volume_del(vol); -} - -/* Callback for UDisks signal "Changed" */ -static void -_places_udisks_device_changed_cb(void *data, const EDBus_Message *msg) -{ - Volume *vol = data; - - if (!vol) return; - edbus_proxy_property_get_all((EDBus_Proxy *)vol->backend_data, - _places_udisks_vol_props_cb, vol); -} - -/* Callback for edbus_proxy_property_get_all() */ -static void -_places_udisks_vol_props_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending) -{ - Volume *vol = data; - EDBus_Message_Iter *array, *dict; - - const char *label = NULL; - const char *partition_label = NULL; - const char *device = NULL; - const char *mount_point = NULL; - const char *drive_type = NULL; - const char *fstype = NULL; - const char *bus = NULL; - const char *model = NULL; - const char *serial = NULL; - const char *vendor = NULL; - const char *id_usage = NULL; - Eina_Bool mounted = EINA_FALSE; - Eina_Bool unlocked = EINA_FALSE; - Eina_Bool removable = EINA_FALSE; - Eina_Bool requires_eject = EINA_FALSE; - Eina_Bool can_detach = EINA_FALSE; - Eina_Bool encrypted = EINA_FALSE; - Eina_Bool media_available = EINA_FALSE; - unsigned long long size = 0; - - EINA_SAFETY_ON_TRUE_RETURN(edbus_message_error_get(msg, NULL, NULL)); - EINA_SAFETY_ON_FALSE_RETURN(edbus_message_arguments_get(msg, "a{sv}", &array)); - - // collect usefull props iterating over the dict - while (edbus_message_iter_get_and_next(array, 'e', &dict)) - { - EDBus_Message_Iter *var; - const char *key; - Eina_Bool bool; - - if (!edbus_message_iter_arguments_get(dict, "sv", &key, &var)) - continue; - - // skip volumes with volume.ignore set - if (!strcmp(key, "DeviceIsMediaChangeDetectionInhibited")) - { - edbus_message_iter_arguments_get(var, "b", &bool); - if (bool) return; - } - else if (!strcmp(key, "IdUsage")) - edbus_message_iter_arguments_get(var, "s", &id_usage); - else if (!strcmp(key, "DeviceFile")) - edbus_message_iter_arguments_get(var, "s", &device); - else if (!strcmp(key, "IdLabel")) - edbus_message_iter_arguments_get(var, "s", &label); - else if (!strcmp(key, "PartitionLabel")) - edbus_message_iter_arguments_get(var, "s", &partition_label); - else if (!strcmp(key, "IdType")) - edbus_message_iter_arguments_get(var, "s", &fstype); - else if (!strcmp(key, "DriveModel")) - edbus_message_iter_arguments_get(var, "s", &model); - else if (!strcmp(key, "DriveSerial")) - edbus_message_iter_arguments_get(var, "s", &serial); - else if (!strcmp(key, "DriveVendor")) - edbus_message_iter_arguments_get(var, "s", &vendor); - else if (!strcmp(key, "DriveConnectionInterface")) - edbus_message_iter_arguments_get(var, "s", &bus); - else if (!strcmp(key, "DeviceMountPaths")) - { - EDBus_Message_Iter *inner_array; - if (!edbus_message_iter_arguments_get(var, "as", &inner_array)) - continue; - edbus_message_iter_get_and_next(inner_array, 's', &mount_point); - } - else if (!strcmp(key, "DriveMediaCompatibility")) - { - EDBus_Message_Iter *inner_array; - if (!edbus_message_iter_arguments_get(var, "as", &inner_array)) - continue; - edbus_message_iter_get_and_next(inner_array, 's', &drive_type); - } - else if (!strcmp(key, "DeviceIsLuks")) - edbus_message_iter_arguments_get(var, "b", &encrypted); - else if (!strcmp(key, "DeviceIsMounted")) - edbus_message_iter_arguments_get(var, "b", &mounted); - else if (!strcmp(key, "DeviceIsLuksCleartext")) - edbus_message_iter_arguments_get(var, "b", &unlocked); - else if (!strcmp(key, "DeviceIsRemovable")) - edbus_message_iter_arguments_get(var, "b", &removable); - else if (!strcmp(key, "DriveIsMediaEjectable")) - edbus_message_iter_arguments_get(var, "b", &requires_eject); - else if (!strcmp(key, "DeviceIsMediaAvailable")) - edbus_message_iter_arguments_get(var, "b", &media_available); - else if (!strcmp(key, "DriveCanDetach")) - edbus_message_iter_arguments_get(var, "b", &can_detach); - else if (!strcmp(key, "DeviceSize")) - edbus_message_iter_arguments_get(var, "t", &size); - } - - // a cdrom has been ejected, invalidate the drive to 'hide' it - if (!media_available && vol->valid) - { - vol->valid = EINA_FALSE; - places_update_all_gadgets(); - return; - } - - // skip volumes that aren't filesystems or crypto - if (!id_usage || !id_usage[0]) return; - if (!strcmp(id_usage, "crypto") && !encrypted) - return; - else if (strcmp(id_usage, "filesystem")) - return; - - // choose the best label - if (partition_label && partition_label[0]) - eina_stringshare_replace(&vol->label, partition_label); - else if (label && label[0]) - eina_stringshare_replace(&vol->label, label); - else if (mount_point && mount_point[0]) - eina_stringshare_replace(&vol->label, mount_point); - else if (device && device[0]) - eina_stringshare_replace(&vol->label, device); - - // store all other props in the Volume* - if (device) eina_stringshare_replace(&vol->device, device); - if (mount_point) eina_stringshare_replace(&vol->mount_point, mount_point); - if (fstype) eina_stringshare_replace(&vol->fstype, fstype); - if (model) eina_stringshare_replace(&vol->model, model); - if (serial) eina_stringshare_replace(&vol->serial, serial); - if (vendor) eina_stringshare_replace(&vol->vendor, vendor); - if (bus) eina_stringshare_replace(&vol->bus, bus); - if (drive_type) eina_stringshare_replace(&vol->drive_type, drive_type); - vol->mounted = mounted; - vol->unlocked = unlocked; - vol->removable = removable; - vol->requires_eject = requires_eject || can_detach; - vol->encrypted = encrypted; - vol->size = size; - - if (!vol->valid) - { - vol->valid = EINA_TRUE; - // trigger a full redraw, is the only way to show a new device - places_update_all_gadgets(); - } - - // the update is always needed to trigger auto_mount/auto_open - places_volume_update(vol); -} - -static void -_places_udisks_volume_task_cb(void *data, const EDBus_Message *msg, - EDBus_Pending *pending) -{ - // Volume *vol = data; - - // TODO alert if the operation has failed - // printf("sig: '%s'\n", edbus_message_signature_get(msg)); - // char *str; - // edbus_message_arguments_get(msg,"s", &str); - // printf("%s\n", str); -} - -static void -_places_udisks_mount_func(Volume *vol, Eina_List *opts) -{ - EDBus_Proxy *proxy = vol->backend_data; - EDBus_Message_Iter *array, *main_iter; - EDBus_Message *msg; - Eina_List *l; - const char *opt_txt; - - if (!proxy) return; - - msg = edbus_proxy_method_call_new(proxy, "FilesystemMount"); - main_iter = edbus_message_iter_get(msg); - edbus_message_iter_arguments_append(main_iter, "sas", vol->fstype, &array); - EINA_LIST_FOREACH(opts, l, opt_txt) - { - // printf(" opt: '%s'\n", opt_txt); - edbus_message_iter_basic_append(array, 's', opt_txt); - } - edbus_message_iter_container_close(main_iter, array); - - edbus_proxy_send(proxy, msg, _places_udisks_volume_task_cb, vol, -1); -} - -static void -_places_udisks_unmount_func(Volume *vol, Eina_List *opts) -{ - EDBus_Proxy *proxy = vol->backend_data; - EDBus_Message_Iter *array, *main_iter; - EDBus_Message *msg; - - if (!proxy) return; - - msg = edbus_proxy_method_call_new(proxy, "FilesystemUnmount"); - main_iter = edbus_message_iter_get(msg); - edbus_message_iter_arguments_append(main_iter, "as", &array); - // here we can use the force option if needed - edbus_message_iter_container_close(main_iter, array); - - edbus_proxy_send(proxy, msg, _places_udisks_volume_task_cb, vol, -1); -} - -static void -_places_udisks_eject_func(Volume *vol, Eina_List *opts) -{ - EDBus_Proxy *proxy = vol->backend_data; - EDBus_Message_Iter *array, *main_iter; - EDBus_Message *msg; - - if (!proxy) return; - - msg = edbus_proxy_method_call_new(proxy, "DriveEject"); - // msg = edbus_proxy_method_call_new(proxy, "DriveDetach"); - main_iter = edbus_message_iter_get(msg); - edbus_message_iter_arguments_append(main_iter, "as", &array); - edbus_message_iter_container_close(main_iter, array); - - edbus_proxy_send(proxy, msg, _places_udisks_volume_task_cb, vol, -1); -} - -static void -_places_udisks_free_func(Volume *vol) -{ - EDBus_Object *obj; - EDBus_Proxy *proxy; - - if (vol->backend_data) - { - proxy = vol->backend_data; - obj = edbus_proxy_object_get(proxy); - - if (proxy) edbus_proxy_unref(proxy); - if (obj) edbus_object_unref(obj); - - vol->backend_data = NULL; - } -} - -#endif diff --git a/src/e_mod_udisks_edbus2.h b/src/e_mod_udisks_edbus2.h deleted file mode 100644 index c51b487..0000000 --- a/src/e_mod_udisks_edbus2.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef E_MOD_PLACES_UDISKS_EDBUS2_H -#define E_MOD_PLACES_UDISKS_EDBUS2_H - -void places_udisks_edbus2_init(void); -void places_udisks_edbus2_shutdown(void); - -#endif - diff --git a/src/e_mod_udisks_eldbus.c b/src/e_mod_udisks_eldbus.c new file mode 100644 index 0000000..4992d89 --- /dev/null +++ b/src/e_mod_udisks_eldbus.c @@ -0,0 +1,417 @@ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_ELDBUS + +#include +#include +#include "e_mod_places.h" + + +/* Local Function Prototypes */ +static void _places_udisks_name_start(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending); +static void _places_udisks_enumerate_devices_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending); +static void _places_udisks_device_add_cb(void *data, const Eldbus_Message *msg); +static void _places_udisks_device_del_cb(void *data, const Eldbus_Message *msg); +static void _places_udisks_device_changed_cb(void *data, const Eldbus_Message *msg); +static void _places_udisks_vol_props_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending); + +static Volume* _places_udisks_volume_add(const char *devpath, Eina_Bool first_time); +static void _places_udisks_mount_func(Volume *vol, Eina_List *opts); +static void _places_udisks_unmount_func(Volume *vol, Eina_List *opts); +static void _places_udisks_eject_func(Volume *vol, Eina_List *opts); +static void _places_udisks_free_func(Volume *vol); + + +/* Local Variables */ +#define UDISKS_BUS "org.freedesktop.UDisks" +#define UDISKS_PATH "/org/freedesktop/UDisks" +#define UDISKS_IFACE "org.freedesktop.UDisks" +#define UDISKS_DEVICE_IFACE "org.freedesktop.UDisks.Device" + +static Eldbus_Connection *_places_dbus_conn = NULL; +static Eldbus_Proxy *_places_udisks_proxy = NULL; + + +/* API */ +Eina_Bool +places_udisks_eldbus_init(void) +{ + printf("PLACES: udisks2: init()\n"); + + if (!eldbus_init()) + return EINA_FALSE; + + _places_dbus_conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM); + if (!_places_dbus_conn) + { + printf("PLACES: udisks2: Error connecting to system bus. Is it running?\n"); + return EINA_FALSE; + } + + eldbus_name_start(_places_dbus_conn, UDISKS_BUS, 0, + _places_udisks_name_start, NULL); + + return EINA_TRUE; +} + +void +places_udisks_eldbus_shutdown(void) +{ + if (_places_udisks_proxy) eldbus_proxy_unref(_places_udisks_proxy); + if (_places_dbus_conn) eldbus_connection_unref(_places_dbus_conn); + eldbus_shutdown(); +} + +/* Implementation */ +static void +_places_udisks_name_start(void *data, const Eldbus_Message *msg, + Eldbus_Pending *pending) +{ + Eldbus_Object *obj; + unsigned flag; + + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_arguments_get(msg, "u", &flag)); + + obj = eldbus_object_get(_places_dbus_conn, UDISKS_BUS, UDISKS_PATH); + _places_udisks_proxy = eldbus_proxy_get(obj, UDISKS_IFACE); + + eldbus_proxy_call(_places_udisks_proxy, "EnumerateDevices", + _places_udisks_enumerate_devices_cb, NULL, -1, ""); + + eldbus_proxy_signal_handler_add(_places_udisks_proxy, "DeviceAdded", + _places_udisks_device_add_cb, NULL); + eldbus_proxy_signal_handler_add(_places_udisks_proxy, "DeviceRemoved", + _places_udisks_device_del_cb, NULL); +} + +static Volume* +_places_udisks_volume_add(const char *devpath, Eina_Bool first_time) +{ + Eldbus_Object *obj; + Eldbus_Proxy *proxy; + Volume *vol; + + // create the Eldbus object and proxy + obj = eldbus_object_get(_places_dbus_conn, UDISKS_BUS, devpath); + if (!obj) return NULL; + proxy = eldbus_proxy_get(obj, UDISKS_DEVICE_IFACE); + if (!proxy) return NULL; + + // create the places volume + vol = places_volume_add(devpath, first_time); + if (!vol) return NULL; + vol->backend_data = proxy; + vol->mount_func = _places_udisks_mount_func; + vol->unmount_func = _places_udisks_unmount_func; + vol->eject_func = _places_udisks_eject_func; + vol->free_func = _places_udisks_free_func; + + // get notification when the dive change + eldbus_proxy_signal_handler_add(proxy, "Changed", + _places_udisks_device_changed_cb, vol); + + return vol; +} + +/* Callback of UDisks method "EnumerateDevices()" */ +static void +_places_udisks_enumerate_devices_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) +{ + Eldbus_Message_Iter *ao; + const char *devpath; + + EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL)); + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_arguments_get(msg, "ao", &ao)); + + while (eldbus_message_iter_get_and_next(ao, 'o', &devpath)) + { + Volume *vol; + vol = _places_udisks_volume_add(devpath, EINA_TRUE); + if (!vol) return; + eldbus_proxy_property_get_all((Eldbus_Proxy *)vol->backend_data, + _places_udisks_vol_props_cb, vol); + } +} + +/* Callback for UDisks signal "DeviceAdded" */ +static void +_places_udisks_device_add_cb(void *data, const Eldbus_Message *msg) +{ + Volume *vol; + char *devpath; + + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_arguments_get(msg, "o", &devpath)); + printf("PLACES udisks: DeviceAdded [%s]\n", devpath); + + if ((vol = _places_udisks_volume_add(devpath, EINA_FALSE))) + eldbus_proxy_property_get_all((Eldbus_Proxy *)vol->backend_data, + _places_udisks_vol_props_cb, vol); +} + +/* Callback for UDisks signal "DeviceRemoved" */ +static void +_places_udisks_device_del_cb(void *data, const Eldbus_Message *msg) +{ + Volume *vol; + char *devpath; + + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_arguments_get(msg, "o", &devpath)); + + if ((vol = places_volume_by_id_get(devpath))) + places_volume_del(vol); +} + +/* Callback for UDisks signal "Changed" */ +static void +_places_udisks_device_changed_cb(void *data, const Eldbus_Message *msg) +{ + Volume *vol = data; + + if (!vol) return; + eldbus_proxy_property_get_all((Eldbus_Proxy *)vol->backend_data, + _places_udisks_vol_props_cb, vol); +} + +/* Callback for eldbus_proxy_property_get_all() */ +static void +_places_udisks_vol_props_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) +{ + Volume *vol = data; + Eldbus_Message_Iter *array, *dict; + + const char *label = NULL; + const char *partition_label = NULL; + const char *device = NULL; + const char *mount_point = NULL; + const char *drive_type = NULL; + const char *fstype = NULL; + const char *bus = NULL; + const char *model = NULL; + const char *serial = NULL; + const char *vendor = NULL; + const char *id_usage = NULL; + Eina_Bool mounted = EINA_FALSE; + Eina_Bool unlocked = EINA_FALSE; + Eina_Bool removable = EINA_FALSE; + Eina_Bool requires_eject = EINA_FALSE; + Eina_Bool can_detach = EINA_FALSE; + Eina_Bool encrypted = EINA_FALSE; + Eina_Bool media_available = EINA_FALSE; + unsigned long long size = 0; + + EINA_SAFETY_ON_TRUE_RETURN(eldbus_message_error_get(msg, NULL, NULL)); + EINA_SAFETY_ON_FALSE_RETURN(eldbus_message_arguments_get(msg, "a{sv}", &array)); + + // collect usefull props iterating over the dict + while (eldbus_message_iter_get_and_next(array, 'e', &dict)) + { + Eldbus_Message_Iter *var; + const char *key; + Eina_Bool bool; + + if (!eldbus_message_iter_arguments_get(dict, "sv", &key, &var)) + continue; + + // skip volumes with volume.ignore set + if (!strcmp(key, "DeviceIsMediaChangeDetectionInhibited")) + { + eldbus_message_iter_arguments_get(var, "b", &bool); + if (bool) return; + } + else if (!strcmp(key, "IdUsage")) + eldbus_message_iter_arguments_get(var, "s", &id_usage); + else if (!strcmp(key, "DeviceFile")) + eldbus_message_iter_arguments_get(var, "s", &device); + else if (!strcmp(key, "IdLabel")) + eldbus_message_iter_arguments_get(var, "s", &label); + else if (!strcmp(key, "PartitionLabel")) + eldbus_message_iter_arguments_get(var, "s", &partition_label); + else if (!strcmp(key, "IdType")) + eldbus_message_iter_arguments_get(var, "s", &fstype); + else if (!strcmp(key, "DriveModel")) + eldbus_message_iter_arguments_get(var, "s", &model); + else if (!strcmp(key, "DriveSerial")) + eldbus_message_iter_arguments_get(var, "s", &serial); + else if (!strcmp(key, "DriveVendor")) + eldbus_message_iter_arguments_get(var, "s", &vendor); + else if (!strcmp(key, "DriveConnectionInterface")) + eldbus_message_iter_arguments_get(var, "s", &bus); + else if (!strcmp(key, "DeviceMountPaths")) + { + Eldbus_Message_Iter *inner_array; + if (!eldbus_message_iter_arguments_get(var, "as", &inner_array)) + continue; + eldbus_message_iter_get_and_next(inner_array, 's', &mount_point); + } + else if (!strcmp(key, "DriveMediaCompatibility")) + { + Eldbus_Message_Iter *inner_array; + if (!eldbus_message_iter_arguments_get(var, "as", &inner_array)) + continue; + eldbus_message_iter_get_and_next(inner_array, 's', &drive_type); + } + else if (!strcmp(key, "DeviceIsLuks")) + eldbus_message_iter_arguments_get(var, "b", &encrypted); + else if (!strcmp(key, "DeviceIsMounted")) + eldbus_message_iter_arguments_get(var, "b", &mounted); + else if (!strcmp(key, "DeviceIsLuksCleartext")) + eldbus_message_iter_arguments_get(var, "b", &unlocked); + else if (!strcmp(key, "DeviceIsRemovable")) + eldbus_message_iter_arguments_get(var, "b", &removable); + else if (!strcmp(key, "DriveIsMediaEjectable")) + eldbus_message_iter_arguments_get(var, "b", &requires_eject); + else if (!strcmp(key, "DeviceIsMediaAvailable")) + eldbus_message_iter_arguments_get(var, "b", &media_available); + else if (!strcmp(key, "DriveCanDetach")) + eldbus_message_iter_arguments_get(var, "b", &can_detach); + else if (!strcmp(key, "DeviceSize")) + eldbus_message_iter_arguments_get(var, "t", &size); + } + + // a cdrom has been ejected, invalidate the drive to 'hide' it + if (!media_available && vol->valid) + { + vol->valid = EINA_FALSE; + places_update_all_gadgets(); + return; + } + + // skip volumes that aren't filesystems or crypto + if (!id_usage || !id_usage[0]) return; + if (!strcmp(id_usage, "crypto") && !encrypted) + return; + else if (strcmp(id_usage, "filesystem")) + return; + + // choose the best label + if (partition_label && partition_label[0]) + eina_stringshare_replace(&vol->label, partition_label); + else if (label && label[0]) + eina_stringshare_replace(&vol->label, label); + else if (mount_point && mount_point[0]) + eina_stringshare_replace(&vol->label, mount_point); + else if (device && device[0]) + eina_stringshare_replace(&vol->label, device); + + // store all other props in the Volume* + if (device) eina_stringshare_replace(&vol->device, device); + if (mount_point) eina_stringshare_replace(&vol->mount_point, mount_point); + if (fstype) eina_stringshare_replace(&vol->fstype, fstype); + if (model) eina_stringshare_replace(&vol->model, model); + if (serial) eina_stringshare_replace(&vol->serial, serial); + if (vendor) eina_stringshare_replace(&vol->vendor, vendor); + if (bus) eina_stringshare_replace(&vol->bus, bus); + if (drive_type) eina_stringshare_replace(&vol->drive_type, drive_type); + vol->mounted = mounted; + vol->unlocked = unlocked; + vol->removable = removable; + vol->requires_eject = requires_eject || can_detach; + vol->encrypted = encrypted; + vol->size = size; + + if (!vol->valid) + { + vol->valid = EINA_TRUE; + // trigger a full redraw, is the only way to show a new device + places_update_all_gadgets(); + } + + // the update is always needed to trigger auto_mount/auto_open + places_volume_update(vol); +} + +static void +_places_udisks_volume_task_cb(void *data, const Eldbus_Message *msg, + Eldbus_Pending *pending) +{ + // Volume *vol = data; + + // TODO alert if the operation has failed + // printf("sig: '%s'\n", eldbus_message_signature_get(msg)); + // char *str; + // eldbus_message_arguments_get(msg,"s", &str); + // printf("%s\n", str); +} + +static void +_places_udisks_mount_func(Volume *vol, Eina_List *opts) +{ + Eldbus_Proxy *proxy = vol->backend_data; + Eldbus_Message_Iter *array, *main_iter; + Eldbus_Message *msg; + Eina_List *l; + const char *opt_txt; + + if (!proxy) return; + + msg = eldbus_proxy_method_call_new(proxy, "FilesystemMount"); + main_iter = eldbus_message_iter_get(msg); + eldbus_message_iter_arguments_append(main_iter, "sas", vol->fstype, &array); + EINA_LIST_FOREACH(opts, l, opt_txt) + { + // printf(" opt: '%s'\n", opt_txt); + eldbus_message_iter_basic_append(array, 's', opt_txt); + } + eldbus_message_iter_container_close(main_iter, array); + + eldbus_proxy_send(proxy, msg, _places_udisks_volume_task_cb, vol, -1); +} + +static void +_places_udisks_unmount_func(Volume *vol, Eina_List *opts) +{ + Eldbus_Proxy *proxy = vol->backend_data; + Eldbus_Message_Iter *array, *main_iter; + Eldbus_Message *msg; + + if (!proxy) return; + + msg = eldbus_proxy_method_call_new(proxy, "FilesystemUnmount"); + main_iter = eldbus_message_iter_get(msg); + eldbus_message_iter_arguments_append(main_iter, "as", &array); + // here we can use the force option if needed + eldbus_message_iter_container_close(main_iter, array); + + eldbus_proxy_send(proxy, msg, _places_udisks_volume_task_cb, vol, -1); +} + +static void +_places_udisks_eject_func(Volume *vol, Eina_List *opts) +{ + Eldbus_Proxy *proxy = vol->backend_data; + Eldbus_Message_Iter *array, *main_iter; + Eldbus_Message *msg; + + if (!proxy) return; + + msg = eldbus_proxy_method_call_new(proxy, "DriveEject"); + // msg = eldbus_proxy_method_call_new(proxy, "DriveDetach"); + main_iter = eldbus_message_iter_get(msg); + eldbus_message_iter_arguments_append(main_iter, "as", &array); + eldbus_message_iter_container_close(main_iter, array); + + eldbus_proxy_send(proxy, msg, _places_udisks_volume_task_cb, vol, -1); +} + +static void +_places_udisks_free_func(Volume *vol) +{ + Eldbus_Object *obj; + Eldbus_Proxy *proxy; + + if (vol->backend_data) + { + proxy = vol->backend_data; + obj = eldbus_proxy_object_get(proxy); + + if (proxy) eldbus_proxy_unref(proxy); + if (obj) eldbus_object_unref(obj); + + vol->backend_data = NULL; + } +} + +#endif diff --git a/src/e_mod_udisks_eldbus.h b/src/e_mod_udisks_eldbus.h new file mode 100644 index 0000000..5b345ce --- /dev/null +++ b/src/e_mod_udisks_eldbus.h @@ -0,0 +1,8 @@ +#ifndef E_MOD_PLACES_UDISKS_ELDBUS_H +#define E_MOD_PLACES_UDISKS_ELDBUS_H + +void places_udisks_eldbus_init(void); +void places_udisks_eldbus_shutdown(void); + +#endif +