From a0df11b0b8651dcce96002bf8242d9cfd98c8133 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Wed, 9 Mar 2011 12:40:45 -0500 Subject: [PATCH] Add utility function to get info about a LUN Signed-off-by: David Zeuthen --- data/80-udisks2.rules | 21 ++ data/org.freedesktop.UDisks2.xml | 58 ++++ doc/udisks2-docs.xml | 1 + doc/udisks2-sections.txt | 6 + src/udiskslinuxlun.c | 205 +++++++++++- udisks/Makefile.am | 2 + udisks/udisks.h | 1 + udisks/udisksutil.c | 688 +++++++++++++++++++++++++++++++++++++++ udisks/udisksutil.h | 45 +++ 9 files changed, 1023 insertions(+), 4 deletions(-) create mode 100644 udisks/udisksutil.c create mode 100644 udisks/udisksutil.h diff --git a/data/80-udisks2.rules b/data/80-udisks2.rules index ea72f85..975932b 100644 --- a/data/80-udisks2.rules +++ b/data/80-udisks2.rules @@ -19,3 +19,24 @@ ACTION!="remove", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", ENV{ID_SERIAL} # ATA/ATAPI devices is of type 0x05 and vendor is usually not ATA ACTION!="remove", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", ENV{ID_SERIAL}!="?*", ATTR{type}=="5", IMPORT{program}="ata_id --export $root/bsg/$kernel" ACTION!="remove", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --whitelisted --export --device $root/bsg/$kernel" + +# ------------------------------------------------------------------------ +# Tag floppy drives since they need special care + +# PC floppy drives +# +KERNEL=="fd*", ENV{ID_DRIVE_FLOPPY}="1" + +# USB floppy drives +# +SUBSYSTEMS=="usb", ATTRS{bInterfaceClass}=="08", ATTRS{bInterfaceSubClass}=="04", ENV{ID_DRIVE_FLOPPY}="1" + +# ATA Zip drives +# +ENV{ID_VENDOR}=="*IOMEGA*", ENV{ID_MODEL}=="*ZIP*", ENV{ID_DRIVE_FLOPPY_ZIP}="1" + +# TODO: figure out if the drive supports SD and SDHC and what the current +# kind of media is - right now we just assume SD +KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ENV{DEVTYPE}=="disk", ENV{ID_DRIVE_FLASH_SD}="1", ENV{ID_DRIVE_MEDIA_FLASH_SD}="1" +# ditto for memstick +KERNEL=="mspblk[0-9]", SUBSYSTEMS=="memstick", ENV{DEVTYPE}=="disk", ENV{ID_DRIVE_FLASH_MS}="1", ENV{ID_DRIVE_MEDIA_FLASH_MS}="1" diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml index a53f69e..5ee4f28 100644 --- a/data/org.freedesktop.UDisks2.xml +++ b/data/org.freedesktop.UDisks2.xml @@ -22,7 +22,65 @@ + + + + + + + + + + + + + + diff --git a/doc/udisks2-docs.xml b/doc/udisks2-docs.xml index f1bbcce..3f643da 100644 --- a/doc/udisks2-docs.xml +++ b/doc/udisks2-docs.xml @@ -65,6 +65,7 @@ Library API Reference + diff --git a/doc/udisks2-sections.txt b/doc/udisks2-sections.txt index caa130b..beb80be 100644 --- a/doc/udisks2-sections.txt +++ b/doc/udisks2-sections.txt @@ -1,4 +1,10 @@
+udisksutil +udisks_util_get_size_for_display +udisks_util_get_lun_info +
+ +
udiskserror UDisksError UDISKS_ERROR diff --git a/src/udiskslinuxlun.c b/src/udiskslinuxlun.c index 47432e5..99c0da6 100644 --- a/src/udiskslinuxlun.c +++ b/src/udiskslinuxlun.c @@ -20,6 +20,10 @@ #include "config.h" +#include +#include +#include + #include #include "udisksdaemon.h" @@ -419,6 +423,199 @@ update_iface (UDisksLinuxLun *lun, /* ---------------------------------------------------------------------------------------------------- */ /* org.freedesktop.UDisks.Lun */ +static const struct +{ + const gchar *udev_property; + const gchar *media_name; +} drive_media_mapping[] = +{ + { "ID_DRIVE_FLASH", "flash" }, + { "ID_DRIVE_FLASH_CF", "flash_cf" }, + { "ID_DRIVE_FLASH_MS", "flash_ms" }, + { "ID_DRIVE_FLASH_SM", "flash_sm" }, + { "ID_DRIVE_FLASH_SD", "flash_sd" }, + { "ID_DRIVE_FLASH_SDHC", "flash_sdhc" }, + { "ID_DRIVE_FLASH_MMC", "flash_mmc" }, + { "ID_DRIVE_FLOPPY", "floppy" }, + { "ID_DRIVE_FLOPPY_ZIP", "floppy_zip" }, + { "ID_DRIVE_FLOPPY_JAZ", "floppy_jaz" }, + { "ID_CDROM", "optical_cd" }, + { "ID_CDROM_CD_R", "optical_cd_r" }, + { "ID_CDROM_CD_RW", "optical_cd_rw" }, + { "ID_CDROM_DVD", "optical_dvd" }, + { "ID_CDROM_DVD_R", "optical_dvd_r" }, + { "ID_CDROM_DVD_RW", "optical_dvd_rw" }, + { "ID_CDROM_DVD_RAM", "optical_dvd_ram" }, + { "ID_CDROM_DVD_PLUS_R", "optical_dvd_plus_r" }, + { "ID_CDROM_DVD_PLUS_RW", "optical_dvd_plus_rw" }, + { "ID_CDROM_DVD_PLUS_R_DL", "optical_dvd_plus_r_dl" }, + { "ID_CDROM_DVD_PLUS_RW_DL", "optical_dvd_plus_rw_dl" }, + { "ID_CDROM_BD", "optical_bd" }, + { "ID_CDROM_BD_R", "optical_bd_r" }, + { "ID_CDROM_BD_RE", "optical_bd_re" }, + { "ID_CDROM_HDDVD", "optical_hddvd" }, + { "ID_CDROM_HDDVD_R", "optical_hddvd_r" }, + { "ID_CDROM_HDDVD_RW", "optical_hddvd_rw" }, + { "ID_CDROM_MO", "optical_mo" }, + { "ID_CDROM_MRW", "optical_mrw" }, + { "ID_CDROM_MRW_W", "optical_mrw_w" }, + { NULL, NULL } +}; + +static const struct +{ + const gchar *udev_property; + const gchar *media_name; +} media_mapping[] = +{ + { "ID_DRIVE_MEDIA_FLASH", "flash" }, + { "ID_DRIVE_MEDIA_FLASH_CF", "flash_cf" }, + { "ID_DRIVE_MEDIA_FLASH_MS", "flash_ms" }, + { "ID_DRIVE_MEDIA_FLASH_SM", "flash_sm" }, + { "ID_DRIVE_MEDIA_FLASH_SD", "flash_sd" }, + { "ID_DRIVE_MEDIA_FLASH_SDHC", "flash_sdhc" }, + { "ID_DRIVE_MEDIA_FLASH_MMC", "flash_mmc" }, + { "ID_DRIVE_MEDIA_FLOPPY", "floppy" }, + { "ID_DRIVE_MEDIA_FLOPPY_ZIP", "floppy_zip" }, + { "ID_DRIVE_MEDIA_FLOPPY_JAZ", "floppy_jaz" }, + { "ID_CDROM_MEDIA_CD", "optical_cd" }, + { "ID_CDROM_MEDIA_CD_R", "optical_cd_r" }, + { "ID_CDROM_MEDIA_CD_RW", "optical_cd_rw" }, + { "ID_CDROM_MEDIA_DVD", "optical_dvd" }, + { "ID_CDROM_MEDIA_DVD_R", "optical_dvd_r" }, + { "ID_CDROM_MEDIA_DVD_RW", "optical_dvd_rw" }, + { "ID_CDROM_MEDIA_DVD_RAM", "optical_dvd_ram" }, + { "ID_CDROM_MEDIA_DVD_PLUS_R", "optical_dvd_plus_r" }, + { "ID_CDROM_MEDIA_DVD_PLUS_RW", "optical_dvd_plus_rw" }, + { "ID_CDROM_MEDIA_DVD_PLUS_R_DL", "optical_dvd_plus_r_dl" }, + { "ID_CDROM_MEDIA_DVD_PLUS_RW_DL", "optical_dvd_plus_rw_dl" }, + { "ID_CDROM_MEDIA_BD", "optical_bd" }, + { "ID_CDROM_MEDIA_BD_R", "optical_bd_r" }, + { "ID_CDROM_MEDIA_BD_RE", "optical_bd_re" }, + { "ID_CDROM_MEDIA_HDDVD", "optical_hddvd" }, + { "ID_CDROM_MEDIA_HDDVD_R", "optical_hddvd_r" }, + { "ID_CDROM_MEDIA_HDDVD_RW", "optical_hddvd_rw" }, + { "ID_CDROM_MEDIA_MO", "optical_mo" }, + { "ID_CDROM_MEDIA_MRW", "optical_mrw" }, + { "ID_CDROM_MEDIA_MRW_W", "optical_mrw_w" }, + { NULL, NULL } +}; + +static gint +ptr_str_array_compare (const gchar **a, + const gchar **b) +{ + return g_strcmp0 (*a, *b); +} + +static void +lun_set_media (UDisksLinuxLun *lun, + UDisksLun *iface, + GUdevDevice *device) +{ + guint n; + GPtrArray *media_compat_array; + const gchar *media_in_drive; + + media_compat_array = g_ptr_array_new (); + for (n = 0; drive_media_mapping[n].udev_property != NULL; n++) + { + if (!g_udev_device_has_property (device, drive_media_mapping[n].udev_property)) + continue; + g_ptr_array_add (media_compat_array, (gpointer) drive_media_mapping[n].media_name); + } + g_ptr_array_sort (media_compat_array, (GCompareFunc) ptr_str_array_compare); + g_ptr_array_add (media_compat_array, NULL); + + media_in_drive = ""; + if (udisks_lun_get_size (iface) > 0) + { + for (n = 0; media_mapping[n].udev_property != NULL; n++) + { + if (!g_udev_device_has_property (device, media_mapping[n].udev_property)) + continue; + + media_in_drive = drive_media_mapping[n].media_name; + break; + } + /* If the media isn't set (from e.g. udev rules), just pick the first one in media_compat - note + * that this may be NULL (if we don't know what media is compatible with the drive) which is OK. + */ + if (media_in_drive == NULL) + media_in_drive = ((const gchar **) media_compat_array->pdata)[0]; + } + + udisks_lun_set_media_compatibility (iface, (const gchar* const *) media_compat_array->pdata); + udisks_lun_set_media (iface, media_in_drive); + g_ptr_array_free (media_compat_array, TRUE); +} + +static void +lun_set_size (UDisksLinuxLun *lun, + UDisksLun *iface, + GUdevDevice *device) +{ + gboolean media_available; + + /* figuring out if media is available is a bit tricky */ + media_available = FALSE; + if (udisks_lun_get_media_removable (iface)) + { + /* never try to open optical drives (might cause the door to close) or + * floppy drives (makes noise) + */ + media_available = FALSE; + if (!(g_udev_device_get_property_as_boolean (device, "ID_CDROM") || + g_udev_device_get_property_as_boolean (device, "ID_DRIVE_FLOPPY"))) + { + gint fd; + fd = open (g_udev_device_get_device_file (device), O_RDONLY); + if (fd >= 0) + { + media_available = TRUE; + close (fd); + } + } + else + { + if (g_udev_device_get_property_as_boolean (device, "ID_CDROM_MEDIA")) + media_available = TRUE; + else + media_available = FALSE; + } + } + else + { + media_available = TRUE; + } + + if (media_available) + udisks_lun_set_size (iface, g_udev_device_get_sysfs_attr_as_uint64 (device, "size") * 512); + else + udisks_lun_set_size (iface, 0); +} + + +static void +lun_set_rotation_rate (UDisksLinuxLun *lun, + UDisksLun *iface, + GUdevDevice *device) +{ + gint rate; + + if (!g_udev_device_get_sysfs_attr_as_boolean (device, "queue/rotational")) + { + rate = 0; + } + else + { + rate = -1; + if (g_udev_device_has_property (device, "ID_ATA_ROTATION_RATE_RPM")) + rate = g_udev_device_get_property_as_int (device, "ID_ATA_ROTATION_RATE_RPM"); + } + udisks_lun_set_rotation_rate (iface, rate); +} + static gboolean lun_check (UDisksLinuxLun *lun) { @@ -549,10 +746,10 @@ lun_update (UDisksLinuxLun *lun, } /* common bits go here */ - udisks_lun_set_size (iface, - g_udev_device_get_sysfs_attr_as_uint64 (device, "size") * 512); - - + udisks_lun_set_media_removable (iface, g_udev_device_get_sysfs_attr_as_boolean (device, "removable")); + lun_set_size (lun, iface, device); + lun_set_media (lun, iface, device); + lun_set_rotation_rate (lun, iface, device); out: ; } diff --git a/udisks/Makefile.am b/udisks/Makefile.am index 3d69d3f..b7c40c2 100644 --- a/udisks/Makefile.am +++ b/udisks/Makefile.am @@ -63,6 +63,7 @@ libudisks2include_HEADERS= \ udisksenumtypes.h \ udiskserror.h \ udiskstypes.h \ + udisksutil.h \ udisks-generated.h \ $(NULL) @@ -72,6 +73,7 @@ libudisks2_la_SOURCES = \ udisksenums.h \ udiskserror.h udiskserror.c \ udiskstypes.h \ + udisksutil.h udisksutil.c \ $(NULL) libudisks2_la_CPPFLAGS = \ diff --git a/udisks/udisks.h b/udisks/udisks.h index c702ccc..29c83a4 100644 --- a/udisks/udisks.h +++ b/udisks/udisks.h @@ -32,6 +32,7 @@ #include #include #include +#include #undef __UDISKS_INSIDE_UDISKS_H__ #endif /* __UDISKS_H__ */ diff --git a/udisks/udisksutil.c b/udisks/udisksutil.c new file mode 100644 index 0000000..ca6bc7e --- /dev/null +++ b/udisks/udisksutil.c @@ -0,0 +1,688 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2007-2010 David Zeuthen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "config.h" + +#include + +//#include +#define _(x) x + +#include "udisksutil.h" + +/** + * SECTION:udisksutil + * @title: Miscellaneous Utility Functions + * @short_description: Various Utilities + * + * Various utilities. + */ + +/* ---------------------------------------------------------------------------------------------------- */ + +#define KILOBYTE_FACTOR 1000.0 +#define MEGABYTE_FACTOR (1000.0 * 1000.0) +#define GIGABYTE_FACTOR (1000.0 * 1000.0 * 1000.0) +#define TERABYTE_FACTOR (1000.0 * 1000.0 * 1000.0 * 1000.0) + +#define KIBIBYTE_FACTOR 1024.0 +#define MEBIBYTE_FACTOR (1024.0 * 1024.0) +#define GIBIBYTE_FACTOR (1024.0 * 1024.0 * 1024.0) +#define TEBIBYTE_FACTOR (1024.0 * 1024.0 * 1024.0 * 10242.0) + +static char * +get_pow2_size (guint64 size) +{ + gchar *str; + gdouble displayed_size; + const gchar *unit; + guint digits; + + if (size < MEBIBYTE_FACTOR) + { + displayed_size = (double) size / KIBIBYTE_FACTOR; + unit = "KiB"; + } + else if (size < GIBIBYTE_FACTOR) + { + displayed_size = (double) size / MEBIBYTE_FACTOR; + unit = "MiB"; + } + else if (size < TEBIBYTE_FACTOR) + { + displayed_size = (double) size / GIBIBYTE_FACTOR; + unit = "GiB"; + } + else + { + displayed_size = (double) size / TEBIBYTE_FACTOR; + unit = "TiB"; + } + + if (displayed_size < 10.0) + digits = 1; + else + digits = 0; + + str = g_strdup_printf ("%.*f %s", digits, displayed_size, unit); + + return str; +} + +static char * +get_pow10_size (guint64 size) +{ + gchar *str; + gdouble displayed_size; + const gchar *unit; + guint digits; + + if (size < MEGABYTE_FACTOR) + { + displayed_size = (double) size / KILOBYTE_FACTOR; + unit = "KB"; + } + else if (size < GIGABYTE_FACTOR) + { + displayed_size = (double) size / MEGABYTE_FACTOR; + unit = "MB"; + } + else if (size < TERABYTE_FACTOR) + { + displayed_size = (double) size / GIGABYTE_FACTOR; + unit = "GB"; + } + else + { + displayed_size = (double) size / TERABYTE_FACTOR; + unit = "TB"; + } + + if (displayed_size < 10.0) + digits = 1; + else + digits = 0; + + str = g_strdup_printf ("%.*f %s", digits, displayed_size, unit); + + return str; +} + +/** + * udisks_util_get_size_for_display: + * @size: Size in bytes + * @use_pow2: Whether power-of-two units should be used instead of power-of-ten units. + * @long_string: Whether to produce a long string + * + * Gets a human-readable string that represents @size. + * + * Returns: A string that should be freed with g_free(). + */ +gchar * +udisks_util_get_size_for_display (guint64 size, + gboolean use_pow2, + gboolean long_string) +{ + gchar *str; + + if (long_string) + { + gchar *size_str; + size_str = g_strdup_printf ("%'" G_GINT64_FORMAT, size); + if (use_pow2) + { + gchar *pow2_str; + pow2_str = get_pow2_size (size); + /* Translators: The first %s is the size in power-of-2 units, e.g. '64 KiB' + * the second %s is the size as a number e.g. '65,536 bytes' + */ + str = g_strdup_printf (_("%s (%s bytes)"), pow2_str, size_str); + g_free (pow2_str); + } + else + { + gchar *pow10_str; + pow10_str = get_pow10_size (size); + /* Translators: The first %s is the size in power-of-10 units, e.g. '100 KB' + * the second %s is the size as a number e.g. '100,000 bytes' + */ + str = g_strdup_printf (_("%s (%s bytes)"), pow10_str, size_str); + g_free (pow10_str); + } + + g_free (size_str); + } + else + { + if (use_pow2) + { + str = get_pow2_size (size); + } + else + { + str = get_pow10_size (size); + } + } + return str; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +strv_has (const gchar * const *haystack, + const gchar *needle) +{ + gboolean ret; + guint n; + + ret = FALSE; + + for (n = 0; haystack != NULL && haystack[n] != NULL; n++) + { + if (g_strcmp0 (haystack[n], needle) == 0) + { + ret = TRUE; + goto out; + } + } + + out: + return ret; +} + +static gboolean +strv_has_prefix (const gchar * const *haystack, + const gchar *needle_prefix) +{ + gboolean ret; + guint n; + + ret = FALSE; + + for (n = 0; haystack != NULL && haystack[n] != NULL; n++) + { + if (g_str_has_prefix (haystack[n], needle_prefix)) + { + ret = TRUE; + goto out; + } + } + + out: + return ret; +} + +static const gchar * +lun_get_drive_icon_name (UDisksLun *lun) +{ + const gchar *ret; + const gchar* const *media_compat; + + ret = NULL; + + media_compat = udisks_lun_get_media_compatibility (lun); + + /* TODO: it would probably be nice to export a property whether this device can + * burn discs etc. so we can use the 'drive-optical-recorder' icon when + * applicable. + */ + + /* first, try to switch on media type */ + if (strv_has (media_compat, "optical_cd")) + ret = "drive-optical"; + else if (strv_has (media_compat, "floppy")) + ret = "drive-removable-media-floppy"; + else if (strv_has (media_compat, "floppy_zip")) + ret = "drive-removable-media-floppy-zip"; + else if (strv_has (media_compat, "floppy_jaz")) + ret = "drive-removable-media-floppy-jaz"; + else if (strv_has (media_compat, "flash_cf")) + ret = "drive-removable-media-flash-cf"; + else if (strv_has (media_compat, "flash_ms")) + ret = "drive-removable-media-flash-ms"; + else if (strv_has (media_compat, "flash_sm")) + ret = "drive-removable-media-flash-sm"; + else if (strv_has (media_compat, "flash_sd")) + ret = "drive-removable-media-flash-sd"; + else if (strv_has (media_compat, "flash_sdhc")) + ret = "drive-removable-media-flash-sd"; /* TODO: get icon name for sdhc */ + else if (strv_has (media_compat, "flash_mmc")) + ret = "drive-removable-media-flash-sd"; /* TODO: get icon for mmc */ + else if (strv_has_prefix (media_compat, "flash")) + ret = "drive-removable-media-flash"; + + if (ret != NULL) + goto out; + + /* TODO: check something like connection-interface to choose USB/Firewire/etc icons */ + if (udisks_lun_get_media_removable (lun)) + { + ret = "drive-removable-media"; + goto out; + } + ret = "drive-harddisk"; + + out: + return ret; + +} + +static const struct +{ + const char *disc_type; + const char *icon_name; +} disc_data[] = { + {"optical_cd", "media-optical-cd-rom", }, + {"optical_cd_r", "media-optical-cd-r", }, + {"optical_cd_rw", "media-optical-cd-rw", }, + {"optical_dvd", "media-optical-dvd-rom", }, + {"optical_dvd_r", "media-optical-dvd-r", }, + {"optical_dvd_rw", "media-optical-dvd-rw", }, + {"optical_dvd_ram", "media-optical-dvd-ram", }, + {"optical_dvd_plus_r", "media-optical-dvd-r-plus", }, + {"optical_dvd_plus_rw", "media-optical-dvd-rw-plus", }, + {"optical_dvd_plus_r_dl", "media-optical-dvd-dl-r-plus", }, + {"optical_dvd_plus_rw_dl", "media-optical-dvd-dl-r-plus", }, + {"optical_bd", "media-optical-bd-rom", }, + {"optical_bd_r", "media-optical-bd-r", }, + {"optical_bd_re", "media-optical-bd-re", }, + {"optical_hddvd", "media-optical-hddvd-rom", }, + {"optical_hddvd_r", "media-optical-hddvd-r", }, + {"optical_hddvd_rw", "media-optical-hddvd-rw", }, + {"optical_mo", "media-optical-mo", }, + {"optical_mrw", "media-optical-mrw", }, + {"optical_mrw_w", "media-optical-mrw-w", }, + {NULL, NULL} +}; + +static const gchar * +lun_get_media_icon_name (UDisksLun *lun) +{ + const gchar *ret; + const gchar *media; + + ret = NULL; + + /* first try the media */ + media = udisks_lun_get_media (lun); + if (strlen (media) > 0) + { + if (g_strcmp0 (media, "flash_cf") == 0) + ret = "media-flash-cf"; + else if (g_strcmp0 (media, "flash_ms") == 0) + ret = "media-flash-ms"; + else if (g_strcmp0 (media, "flash_sm") == 0) + ret = "media-flash-sm"; + else if (g_strcmp0 (media, "flash_sd") == 0) + ret = "media-flash-sd"; + else if (g_strcmp0 (media, "flash_sdhc") == 0) + ret = "media-flash-sd"; /* TODO: get icon name for sdhc */ + else if (g_strcmp0 (media, "flash_mmc") == 0) + ret = "media-flash-sd"; /* TODO: get icon for mmc */ + else if (g_strcmp0 (media, "floppy") == 0) + ret = "media-floppy"; + else if (g_strcmp0 (media, "floppy_zip") == 0) + ret = "media-floppy-zip"; + else if (g_strcmp0 (media, "floppy_jaz") == 0) + ret = "media-floppy-jaz"; + else if (g_str_has_prefix (media, "flash")) + ret = "media-flash"; + else if (g_str_has_prefix (media, "optical")) + { + guint n; + for (n = 0; disc_data[n].disc_type != NULL; n++) + { + if (g_strcmp0 (disc_data[n].disc_type, media) == 0) + { + ret = disc_data[n].icon_name; + break; + } + } + if (ret == NULL) + ret = "media-optical"; + } + } + + if (ret != NULL) + goto out; + + /* TODO: check something like connection-interface to choose USB/Firewire/etc icons */ + if (udisks_lun_get_media_removable (lun)) + { + ret = "drive-removable-media"; + goto out; + } + ret = "drive-harddisk"; + + out: + return ret; +} + +static void +get_lun_name_from_media_compat (UDisksLun *lun, + GString *result) +{ + guint n; + gboolean optical_cd; + gboolean optical_dvd; + gboolean optical_bd; + gboolean optical_hddvd; + const gchar* const *media_compat; + + media_compat = udisks_lun_get_media_compatibility (lun); + + optical_cd = FALSE; + optical_dvd = FALSE; + optical_bd = FALSE; + optical_hddvd = FALSE; + + for (n = 0; media_compat != NULL && media_compat[n] != NULL; n++) { + const gchar *media_name; + const gchar *media; + + media = media_compat[n]; + media_name = NULL; + if (g_strcmp0 (media, "flash_cf") == 0) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("CompactFlash"); + } + else if (g_strcmp0 (media, "flash_ms") == 0) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("MemoryStick"); + } + else if (g_strcmp0 (media, "flash_sm") == 0) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("SmartMedia"); + } + else if (g_strcmp0 (media, "flash_sd") == 0) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("SecureDigital"); + } + else if (g_strcmp0 (media, "flash_sdhc") == 0) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("SD High Capacity"); + } + else if (g_strcmp0 (media, "floppy") == 0) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("Floppy"); + } + else if (g_strcmp0 (media, "floppy_zip") == 0) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("Zip"); + } + else if (g_strcmp0 (media, "floppy_jaz") == 0) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("Jaz"); + } + else if (g_str_has_prefix (media, "flash")) + { + /* Translators: This word is used to describe the media inserted into a device */ + media_name = _("Flash"); + } + else if (g_str_has_prefix (media, "optical_cd")) + { + optical_cd = TRUE; + } + else if (g_str_has_prefix (media, "optical_dvd")) + { + optical_dvd = TRUE; + } + else if (g_str_has_prefix (media, "optical_bd")) + { + optical_bd = TRUE; + } + else if (g_str_has_prefix (media, "optical_hddvd")) + { + optical_hddvd = TRUE; + } + + if (media_name != NULL) + { + if (result->len > 0) + g_string_append_c (result, '/'); + g_string_append (result, media_name); + } + } + + if (optical_cd) + { + if (result->len > 0) + g_string_append_c (result, '/'); + /* Translators: This word is used to describe the optical disc type, it may appear + * in a slash-separated list e.g. 'CD/DVD/Blu-Ray' + */ + g_string_append (result, _("CD")); + } + if (optical_dvd) + { + if (result->len > 0) + g_string_append_c (result, '/'); + /* Translators: This word is used to describe the optical disc type, it may appear + * in a slash-separated list e.g. 'CD/DVD/Blu-Ray' + */ + g_string_append (result, _("DVD")); + } + if (optical_bd) + { + if (result->len > 0) + g_string_append_c (result, '/'); + /* Translators: This word is used to describe the optical disc type, it may appear + * in a slash-separated list e.g. 'CD/DVD/Blu-Ray' + */ + g_string_append (result, _("Blu-Ray")); + } + if (optical_hddvd) + { + if (result->len > 0) + g_string_append_c (result, '/'); + /* Translators: This word is used to describe the optical disc type, it may appear + * in a slash-separated list e.g. 'CD/DVD/Blu-Ray' + */ + g_string_append (result, _("HDDVD")); + } +} + +/** + * udisks_util_get_lun_info: + * @lun: A #UDisksLun. + * @out_name: (out allow-none): Return location for name or %NULL. + * @out_description: (out allow-none): Return location for description or %NULL. + * @out_drive_icon: (out allow-none): Return location for icon representing the drive or %NULL. + * @out_media_icon: (out allow-none): Return location for icon representing the media or %NULL. + * + * Gets information about a #UDisksLun object that is suitable to + * present in an user interface. The returned information is + * localized. + * + * If the @lun doesn't support removable media, then the returned icon + * for the media is always the same as for the drive. + */ +void +udisks_util_get_lun_info (UDisksLun *lun, + gchar **out_name, + gchar **out_description, + GIcon **out_drive_icon, + GIcon **out_media_icon) +{ + gchar *name; + gchar *description; + const gchar *vendor; + const gchar *model; + guint64 size; + gboolean is_removable; + GString *result; + gboolean rotation_rate; + gchar *strsize; + + g_return_if_fail (UDISKS_IS_LUN (lun)); + + name = NULL; + description = NULL; + + strsize = NULL; + result = g_string_new (NULL); + + /* TODO: support presentation-name for overrides */ + + vendor = udisks_lun_get_vendor (lun); + model = udisks_lun_get_model (lun); + if (strlen (vendor) == 0) + vendor = NULL; + if (strlen (model) == 0) + model = NULL; + + size = udisks_lun_get_size (lun); + + is_removable = udisks_lun_get_media_removable (lun); + rotation_rate = udisks_lun_get_rotation_rate (lun); + + if (size > 0) + strsize = udisks_util_get_size_for_display (size, FALSE, FALSE); + + if (is_removable) + { + get_lun_name_from_media_compat (lun, result); + + /* If we know the media type, just append Drive */ + if (result->len > 0) + { + GString *new_result; + + new_result = g_string_new (NULL); + /* Translators: %s is the media type e.g. 'CD/DVD' or 'CompactFlash' */ + g_string_append_printf (new_result, _("%s Drive"), result->str); + g_string_free (result, TRUE); + result = new_result; + } + else + { + /* Otherwise just "Removable Drive", possibly with the size */ + if (strsize != NULL) + { + g_string_append_printf (result, + _("%s Removable Drive"), + strsize); + } + else + { + g_string_append (result, + _("Removable Drive")); + } + } + } + else + { + /* Media is not removable, use "Hard Disk" resp. "Solid-State Disk" + * unless we actually know what media types the drive is compatible with + */ + get_lun_name_from_media_compat (lun, result); + + if (result->len > 0) + { + GString *new_result; + new_result = g_string_new (NULL); + if (strsize != NULL) + { + /* Translators: first %s is the size, second %s is the media type + * e.g. 'CD/DVD' or 'CompactFlash' + */ + g_string_append_printf (new_result, _("%s %s Drive"), + strsize, + result->str); + } + else + { + /* Translators: %s is the media type e.g. 'CD/DVD' or 'CompactFlash' */ + g_string_append_printf (new_result, _("%s Drive"), + result->str); + } + g_string_free (result, TRUE); + result = new_result; + } + else + { + if (rotation_rate != 0) + { + if (strsize != NULL) + { + /* Translators: This string is used to describe a hard disk. + * The first %s is the size of the drive e.g. '45 GB'. + */ + g_string_append_printf (result, _("%s Hard Disk"), strsize); + } + else + { + /* Translators: This string is used to describe a hard disk where the size + * is not known. + */ + g_string_append (result, _("Hard Disk")); + } + } + else + { + if (strsize != NULL) + { + /* Translators: This string is used to describe a non-rotating disk. The first %s is + * the size of the drive e.g. '45 GB'. + */ + g_string_append_printf (result, _("%s Disk"), + strsize); + } + else + { + /* Translators: This string is used to describe a non-rotating disk where the size + * is not known. + */ + g_string_append (result, _("Disk")); + } + } + } + } + + description = g_string_free (result, FALSE); + + name = g_strdup_printf ("%s%s%s", + vendor != NULL ? vendor : "", + vendor != NULL ? " " : "", + model != NULL ? model : ""); + + if (out_name != NULL) + *out_name = name; + else + g_free (name); + + if (out_description != NULL) + *out_description = description; + else + g_free (description); + + if (out_drive_icon != NULL) + *out_drive_icon = g_themed_icon_new_with_default_fallbacks (lun_get_drive_icon_name (lun)); + if (out_media_icon != NULL) + *out_media_icon = g_themed_icon_new_with_default_fallbacks (lun_get_media_icon_name (lun)); +} diff --git a/udisks/udisksutil.h b/udisks/udisksutil.h new file mode 100644 index 0000000..6d83a5b --- /dev/null +++ b/udisks/udisksutil.h @@ -0,0 +1,45 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2007-2010 David Zeuthen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#if !defined (__UDISKS_INSIDE_UDISKS_H__) && !defined (UDISKS_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __UDISKS_UTIL_H__ +#define __UDISKS_UTIL_H__ + +#include +#include + +G_BEGIN_DECLS + +gchar *udisks_util_get_size_for_display (guint64 size, + gboolean use_pow2, + gboolean long_string); + +void udisks_util_get_lun_info (UDisksLun *lun, + gchar **out_name, + gchar **out_description, + GIcon **out_icon, + GIcon **out_media_icon); + +G_END_DECLS + +#endif /* __UDISKS_UTIL_H__ */ -- 2.7.4