[gnome-disk-utility/new-ui] Show port number of device, if available
- From: David Zeuthen <davidz src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility/new-ui] Show port number of device, if available
- Date: Sat, 28 Nov 2009 19:41:31 +0000 (UTC)
commit 7bc36f0f887c74ebfdf3298befdbc955aa3b0989
Author: David Zeuthen <davidz redhat com>
Date: Sat Nov 28 14:40:35 2009 -0500
Show port number of device, if available
src/gdu/Makefile.am | 8 +-
src/gdu/gdu-adapter.c | 23 +++-
src/gdu/gdu-adapter.h | 2 +
src/gdu/gdu-device.c | 10 ++
src/gdu/gdu-device.h | 1 +
src/gdu/gdu-pool.c | 236 +++++++++++++++++++++++++++-
src/gdu/gdu-pool.h | 13 ++-
src/gdu/gdu-port.c | 314 ++++++++++++++++++++++++++++++++++++
src/gdu/gdu-port.h | 75 +++++++++
src/gdu/gdu-private.h | 7 +-
src/gdu/gdu-types.h | 1 +
src/gdu/gdu.h | 1 +
src/palimpsest/gdu-section-drive.c | 37 +++++
13 files changed, 719 insertions(+), 9 deletions(-)
---
diff --git a/src/gdu/Makefile.am b/src/gdu/Makefile.am
index b873e46..7594045 100644
--- a/src/gdu/Makefile.am
+++ b/src/gdu/Makefile.am
@@ -4,6 +4,7 @@ BUILT_SOURCES = \
devkit-disks-daemon-glue.h \
devkit-disks-device-glue.h \
devkit-disks-adapter-glue.h \
+ devkit-disks-port-glue.h \
gdu-marshal.h gdu-marshal.c
gdu-marshal.h: gdu-marshal.list
@@ -21,6 +22,9 @@ devkit-disks-device-glue.h: /usr/share/dbus-1/interfaces/org.freedesktop.DeviceK
devkit-disks-adapter-glue.h: /usr/share/dbus-1/interfaces/org.freedesktop.DeviceKit.Disks.Adapter.xml Makefile.am
dbus-binding-tool --prefix=devkit_disks_daemon --mode=glib-client --output=devkit-disks-adapter-glue.h /usr/share/dbus-1/interfaces/org.freedesktop.DeviceKit.Disks.Adapter.xml
+devkit-disks-port-glue.h: /usr/share/dbus-1/interfaces/org.freedesktop.DeviceKit.Disks.Port.xml Makefile.am
+ dbus-binding-tool --prefix=devkit_disks_daemon --mode=glib-client --output=devkit-disks-port-glue.h /usr/share/dbus-1/interfaces/org.freedesktop.DeviceKit.Disks.Port.xml
+
lib_LTLIBRARIES=libgdu.la
libgduincludedir=$(includedir)/gnome-disk-utility/gdu
@@ -30,7 +34,8 @@ libgduinclude_HEADERS = \
gdu-types.h \
gdu-callbacks.h \
gdu-device.h \
- gdu-adapter.h \
+ gdu-adapter.h \
+ gdu-port.h \
gdu-drive.h \
gdu-linux-md-drive.h \
gdu-error.h \
@@ -52,6 +57,7 @@ libgdu_la_SOURCES = \
gdu-pool.c gdu-pool.h \
gdu-device.c gdu-device.h \
gdu-adapter.c gdu-adapter.h \
+ gdu-port.c gdu-port.h \
gdu-drive.c gdu-drive.h \
gdu-linux-md-drive.c gdu-linux-md-drive.h \
gdu-volume.c gdu-volume.h \
diff --git a/src/gdu/gdu-adapter.c b/src/gdu/gdu-adapter.c
index 6290ac1..22b5e78 100644
--- a/src/gdu/gdu-adapter.c
+++ b/src/gdu/gdu-adapter.c
@@ -48,6 +48,8 @@ typedef struct
gchar *vendor;
gchar *model;
gchar *driver;
+ gchar *fabric;
+ guint num_ports;
} AdapterProperties;
static void
@@ -64,6 +66,10 @@ collect_props (const char *key, const GValue *value, AdapterProperties *props)
props->model = g_value_dup_string (value);
else if (strcmp (key, "Driver") == 0)
props->driver = g_value_dup_string (value);
+ else if (strcmp (key, "Fabric") == 0)
+ props->fabric = g_value_dup_string (value);
+ else if (strcmp (key, "NumPorts") == 0)
+ props->num_ports = g_value_get_uint (value);
else
handled = FALSE;
@@ -78,6 +84,7 @@ adapter_properties_free (AdapterProperties *props)
g_free (props->vendor);
g_free (props->model);
g_free (props->driver);
+ g_free (props->fabric);
g_free (props);
}
@@ -119,12 +126,14 @@ adapter_properties_get (DBusGConnection *bus,
g_hash_table_unref (hash_table);
-#if 0
+#if 1
g_print ("----------------------------------------------------------------------\n");
g_print ("native_path: %s\n", props->native_path);
g_print ("vendor: %s\n", props->vendor);
g_print ("model: %s\n", props->model);
g_print ("driver: %s\n", props->driver);
+ g_print ("fabric: %s\n", props->fabric);
+ g_print ("num_ports: %d\n", props->num_ports);
#endif
out:
@@ -313,3 +322,15 @@ gdu_adapter_get_driver (GduAdapter *adapter)
{
return adapter->priv->props->driver;
}
+
+const gchar *
+gdu_adapter_get_fabric (GduAdapter *adapter)
+{
+ return adapter->priv->props->fabric;
+}
+
+guint
+gdu_adapter_get_num_ports (GduAdapter *adapter)
+{
+ return adapter->priv->props->num_ports;
+}
diff --git a/src/gdu/gdu-adapter.h b/src/gdu/gdu-adapter.h
index eb69307..fd57b5b 100644
--- a/src/gdu/gdu-adapter.h
+++ b/src/gdu/gdu-adapter.h
@@ -69,6 +69,8 @@ const gchar *gdu_adapter_get_native_path (GduAdapter *adapter);
const gchar *gdu_adapter_get_vendor (GduAdapter *adapter);
const gchar *gdu_adapter_get_model (GduAdapter *adapter);
const gchar *gdu_adapter_get_driver (GduAdapter *adapter);
+const gchar *gdu_adapter_get_fabric (GduAdapter *adapter);
+guint gdu_adapter_get_num_ports (GduAdapter *adapter);
G_END_DECLS
diff --git a/src/gdu/gdu-device.c b/src/gdu/gdu-device.c
index dd0ecda..88b977c 100644
--- a/src/gdu/gdu-device.c
+++ b/src/gdu/gdu-device.c
@@ -124,6 +124,7 @@ typedef struct
guint drive_rotation_rate;
char *drive_write_cache;
char *drive_adapter;
+ char *drive_port;
gboolean optical_disc_is_blank;
gboolean optical_disc_is_appendable;
@@ -321,6 +322,8 @@ collect_props (const char *key, const GValue *value, DeviceProperties *props)
props->drive_write_cache = g_strdup (g_value_get_string (value));
else if (strcmp (key, "DriveAdapter") == 0)
props->drive_adapter = g_strdup (g_value_get_boxed (value));
+ else if (strcmp (key, "DrivePort") == 0)
+ props->drive_port = g_strdup (g_value_get_boxed (value));
else if (strcmp (key, "OpticalDiscIsBlank") == 0)
props->optical_disc_is_blank = g_value_get_boolean (value);
@@ -442,6 +445,7 @@ device_properties_free (DeviceProperties *props)
g_free (props->drive_media);
g_free (props->drive_write_cache);
g_free (props->drive_adapter);
+ g_free (props->drive_port);
g_free (props->drive_ata_smart_status);
g_free (props->drive_ata_smart_blob);
@@ -1092,6 +1096,12 @@ gdu_device_drive_get_adapter (GduDevice *device)
return device->priv->props->drive_adapter;
}
+const char *
+gdu_device_drive_get_port (GduDevice *device)
+{
+ return device->priv->props->drive_port;
+}
+
gboolean
gdu_device_drive_get_is_media_ejectable (GduDevice *device)
{
diff --git a/src/gdu/gdu-device.h b/src/gdu/gdu-device.h
index d294450..78d9855 100644
--- a/src/gdu/gdu-device.h
+++ b/src/gdu/gdu-device.h
@@ -145,6 +145,7 @@ gboolean gdu_device_drive_get_is_rotational (GduDevice *device);
guint gdu_device_drive_get_rotation_rate (GduDevice *device);
const char *gdu_device_drive_get_write_cache (GduDevice *device);
const char *gdu_device_drive_get_adapter (GduDevice *device);
+const char *gdu_device_drive_get_port (GduDevice *device);
gboolean gdu_device_optical_disc_get_is_blank (GduDevice *device);
gboolean gdu_device_optical_disc_get_is_appendable (GduDevice *device);
diff --git a/src/gdu/gdu-pool.c b/src/gdu/gdu-pool.c
index a4b232d..69c1c5f 100644
--- a/src/gdu/gdu-pool.c
+++ b/src/gdu/gdu-pool.c
@@ -28,6 +28,7 @@
#include "gdu-presentable.h"
#include "gdu-device.h"
#include "gdu-adapter.h"
+#include "gdu-port.h"
#include "gdu-drive.h"
#include "gdu-linux-md-drive.h"
#include "gdu-volume.h"
@@ -54,6 +55,9 @@ enum {
ADAPTER_ADDED,
ADAPTER_REMOVED,
ADAPTER_CHANGED,
+ PORT_ADDED,
+ PORT_REMOVED,
+ PORT_CHANGED,
PRESENTABLE_ADDED,
PRESENTABLE_REMOVED,
PRESENTABLE_CHANGED,
@@ -79,8 +83,11 @@ struct _GduPoolPrivate
/* the current set of devices we know about */
GHashTable *object_path_to_device;
- /* the current set of devices we know about */
+ /* the current set of adapters we know about */
GHashTable *object_path_to_adapter;
+
+ /* the current set of ports we know about */
+ GHashTable *object_path_to_port;
};
G_DEFINE_TYPE (GduPool, gdu_pool, G_TYPE_OBJECT);
@@ -100,6 +107,8 @@ gdu_pool_finalize (GduPool *pool)
g_hash_table_unref (pool->priv->object_path_to_adapter);
+ g_hash_table_unref (pool->priv->object_path_to_port);
+
g_list_foreach (pool->priv->presentables, (GFunc) g_object_unref, NULL);
g_list_free (pool->priv->presentables);
@@ -239,6 +248,58 @@ gdu_pool_class_init (GduPoolClass *klass)
G_TYPE_NONE, 1,
GDU_TYPE_ADAPTER);
+ /**
+ * GduPool::port-added
+ * @pool: The #GduPool emitting the signal.
+ * @port: The #GduPort that was added.
+ *
+ * Emitted when @port is added to @pool.
+ **/
+ signals[PORT_ADDED] =
+ g_signal_new ("port-added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GduPoolClass, port_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GDU_TYPE_PORT);
+
+ /**
+ * GduPool::port-removed
+ * @pool: The #GduPool emitting the signal.
+ * @port: The #GduPort that was removed.
+ *
+ * Emitted when @port is removed from @pool. Recipients
+ * should release references to @port.
+ **/
+ signals[PORT_REMOVED] =
+ g_signal_new ("port-removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GduPoolClass, port_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GDU_TYPE_PORT);
+
+ /**
+ * GduPool::port-changed
+ * @pool: The #GduPool emitting the signal.
+ * @port: A #GduPort.
+ *
+ * Emitted when @port is changed.
+ **/
+ signals[PORT_CHANGED] =
+ g_signal_new ("port-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GduPoolClass, port_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GDU_TYPE_PORT);
+
/**
* GduPool::presentable-added
@@ -356,6 +417,11 @@ gdu_pool_init (GduPool *pool)
g_str_equal,
NULL,
g_object_unref);
+
+ pool->priv->object_path_to_port = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ g_object_unref);
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1183,6 +1249,96 @@ adapter_changed_signal_handler (DBusGProxy *proxy, const char *object_path, gpoi
/* ---------------------------------------------------------------------------------------------------- */
+static void
+port_changed_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data);
+
+static void
+port_added_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data)
+{
+ GduPool *pool;
+ GduPort *port;
+
+ pool = GDU_POOL (user_data);
+
+ port = gdu_pool_get_port_by_object_path (pool, object_path);
+ if (port != NULL) {
+ g_object_unref (port);
+ g_warning ("Treating add for previously added port %s as change", object_path);
+ port_changed_signal_handler (proxy, object_path, user_data);
+ goto out;
+ }
+
+ port = _gdu_port_new_from_object_path (pool, object_path);
+ if (port == NULL)
+ goto out;
+
+ g_hash_table_insert (pool->priv->object_path_to_port,
+ (gpointer) gdu_port_get_object_path (port),
+ port);
+ g_signal_emit (pool, signals[PORT_ADDED], 0, port);
+ //g_debug ("Added port %s", object_path);
+
+ recompute_presentables (pool);
+
+ out:
+ ;
+}
+
+static void
+port_removed_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data)
+{
+ GduPool *pool;
+ GduPort *port;
+
+ pool = GDU_POOL (user_data);
+
+ port = gdu_pool_get_port_by_object_path (pool, object_path);
+ if (port == NULL) {
+ g_warning ("No port to remove for remove %s", object_path);
+ goto out;
+ }
+
+ g_hash_table_remove (pool->priv->object_path_to_port,
+ gdu_port_get_object_path (port));
+ g_signal_emit (pool, signals[PORT_REMOVED], 0, port);
+ g_signal_emit_by_name (port, "removed");
+ g_object_unref (port);
+ g_debug ("Removed port %s", object_path);
+
+ recompute_presentables (pool);
+
+ out:
+ ;
+}
+
+static void
+port_changed_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data)
+{
+ GduPool *pool;
+ GduPort *port;
+
+ pool = GDU_POOL (user_data);
+
+ port = gdu_pool_get_port_by_object_path (pool, object_path);
+ if (port == NULL) {
+ g_warning ("Ignoring change event on non-existant port %s", object_path);
+ goto out;
+ }
+
+ if (_gdu_port_changed (port)) {
+ g_signal_emit (pool, signals[PORT_CHANGED], 0, port);
+ g_signal_emit_by_name (port, "changed");
+ }
+ g_object_unref (port);
+
+ recompute_presentables (pool);
+
+ out:
+ ;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static gboolean
get_properties (GduPool *pool)
{
@@ -1264,6 +1420,7 @@ gdu_pool_new (void)
int n;
GPtrArray *devices;
GPtrArray *adapters;
+ GPtrArray *ports;
GduPool *pool;
GError *error;
@@ -1324,6 +1481,16 @@ gdu_pool_new (void)
dbus_g_proxy_connect_signal (pool->priv->proxy, "AdapterChanged",
G_CALLBACK (adapter_changed_signal_handler), pool, NULL);
+ dbus_g_proxy_add_signal (pool->priv->proxy, "PortAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (pool->priv->proxy, "PortRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (pool->priv->proxy, "PortChanged", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (pool->priv->proxy, "PortAdded",
+ G_CALLBACK (port_added_signal_handler), pool, NULL);
+ dbus_g_proxy_connect_signal (pool->priv->proxy, "PortRemoved",
+ G_CALLBACK (port_removed_signal_handler), pool, NULL);
+ dbus_g_proxy_connect_signal (pool->priv->proxy, "PortChanged",
+ G_CALLBACK (port_changed_signal_handler), pool, NULL);
+
/* get the properties on the daemon object at / */
if (!get_properties (pool)) {
g_warning ("Couldn't get daemon properties");
@@ -1377,6 +1544,28 @@ gdu_pool_new (void)
g_ptr_array_foreach (adapters, (GFunc) g_free, NULL);
g_ptr_array_free (adapters, TRUE);
+ /* prime the list of ports */
+ error = NULL;
+ if (!org_freedesktop_DeviceKit_Disks_enumerate_ports (pool->priv->proxy, &ports, &error)) {
+ g_warning ("Couldn't enumerate ports: %s", error->message);
+ g_error_free (error);
+ goto error;
+ }
+ for (n = 0; n < (int) ports->len; n++) {
+ const char *object_path;
+ GduPort *port;
+
+ object_path = ports->pdata[n];
+
+ port = _gdu_port_new_from_object_path (pool, object_path);
+
+ g_hash_table_insert (pool->priv->object_path_to_port,
+ (gpointer) gdu_port_get_object_path (port),
+ port);
+ }
+ g_ptr_array_foreach (ports, (GFunc) g_free, NULL);
+ g_ptr_array_free (ports, TRUE);
+
/* and finally compute all presentables */
recompute_presentables (pool);
@@ -1432,6 +1621,28 @@ gdu_pool_get_adapter_by_object_path (GduPool *pool, const char *object_path)
}
/**
+ * gdu_pool_get_by_object_path:
+ * @pool: the pool
+ * @object_path: the D-Bus object path
+ *
+ * Looks up #GduPort object for @object_path.
+ *
+ * Returns: A #GduPort object for @object_path, otherwise
+ * #NULL. Caller must unref this object using g_object_unref().
+ **/
+GduPort *
+gdu_pool_get_port_by_object_path (GduPool *pool, const char *object_path)
+{
+ GduPort *ret;
+
+ ret = g_hash_table_lookup (pool->priv->object_path_to_port, object_path);
+ if (ret != NULL) {
+ g_object_ref (ret);
+ }
+ return ret;
+}
+
+/**
* gdu_pool_get_by_device_file:
* @pool: the device pool
* @device_file: the UNIX block special device file, e.g. /dev/sda1.
@@ -1617,7 +1828,7 @@ gdu_pool_get_devices (GduPool *pool)
* gdu_pool_get_adapters:
* @pool: A #GduPool.
*
- * Get a list of all adapters.
+ * Get a list of all adapters.
*
* Returns: A #GList of #GduAdapter objects. Caller must free this
* (unref all objects, then use g_list_free()).
@@ -1635,6 +1846,27 @@ gdu_pool_get_adapters (GduPool *pool)
}
/**
+ * gdu_pool_get_ports:
+ * @pool: A #GduPool.
+ *
+ * Get a list of all ports.
+ *
+ * Returns: A #GList of #GduPort objects. Caller must free this
+ * (unref all objects, then use g_list_free()).
+ **/
+GList *
+gdu_pool_get_ports (GduPool *pool)
+{
+ GList *ret;
+
+ ret = NULL;
+
+ ret = g_hash_table_get_values (pool->priv->object_path_to_port);
+ g_list_foreach (ret, (GFunc) g_object_ref, NULL);
+ return ret;
+}
+
+/**
* gdu_pool_get_presentables:
* @pool: A #GduPool
*
diff --git a/src/gdu/gdu-pool.h b/src/gdu/gdu-pool.h
index ea2ac84..a44a500 100644
--- a/src/gdu/gdu-pool.h
+++ b/src/gdu/gdu-pool.h
@@ -59,9 +59,13 @@ struct _GduPoolClass
void (*device_changed) (GduPool *pool, GduDevice *device);
void (*device_job_changed) (GduPool *pool, GduDevice *device);
- void (*adapter_added) (GduPool *pool, GduDevice *device);
- void (*adapter_removed) (GduPool *pool, GduDevice *device);
- void (*adapter_changed) (GduPool *pool, GduDevice *device);
+ void (*adapter_added) (GduPool *pool, GduAdapter *adapter);
+ void (*adapter_removed) (GduPool *pool, GduAdapter *adapter);
+ void (*adapter_changed) (GduPool *pool, GduAdapter *adapter);
+
+ void (*port_added) (GduPool *pool, GduPort *port);
+ void (*port_removed) (GduPool *pool, GduPort *port);
+ void (*port_changed) (GduPool *pool, GduPort *port);
void (*presentable_added) (GduPool *pool, GduPresentable *presentable);
void (*presentable_removed) (GduPool *pool, GduPresentable *presentable);
@@ -94,6 +98,9 @@ GList *gdu_pool_get_enclosed_presentables (GduPool *pool, GduPresentable *p
GduAdapter *gdu_pool_get_adapter_by_object_path (GduPool *pool, const char *object_path);
GList *gdu_pool_get_adapters (GduPool *pool);
+GduPort *gdu_pool_get_port_by_object_path (GduPool *pool, const char *object_path);
+GList *gdu_pool_get_ports (GduPool *pool);
+
/* ---------------------------------------------------------------------------------------------------- */
void gdu_pool_op_linux_md_start (GduPool *pool,
diff --git a/src/gdu/gdu-port.c b/src/gdu/gdu-port.c
new file mode 100644
index 0000000..c02c28f
--- /dev/null
+++ b/src/gdu/gdu-port.c
@@ -0,0 +1,314 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* gdu-port.c
+ *
+ * Copyright (C) 2009 David Zeuthen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <dbus/dbus-glib.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "gdu-private.h"
+#include "gdu-pool.h"
+#include "gdu-port.h"
+#include "devkit-disks-port-glue.h"
+
+/* --- SUCKY CODE BEGIN --- */
+
+/* This totally sucks; dbus-bindings-tool and dbus-glib should be able
+ * to do this for us.
+ *
+ * TODO: keep in sync with code in tools/devkit-disks in DeviceKit-disks.
+ */
+
+typedef struct
+{
+ gchar *native_path;
+
+ gchar *adapter;
+ gchar *parent;
+ gint number;
+} PortProperties;
+
+static void
+collect_props (const char *key, const GValue *value, PortProperties *props)
+{
+ gboolean handled = TRUE;
+
+ if (strcmp (key, "NativePath") == 0)
+ props->native_path = g_strdup (g_value_get_string (value));
+
+ else if (strcmp (key, "Adapter") == 0)
+ props->adapter = g_value_dup_boxed (value);
+ else if (strcmp (key, "Parent") == 0)
+ props->parent = g_value_dup_boxed (value);
+ else if (strcmp (key, "Number") == 0)
+ props->number = g_value_get_int (value);
+ else
+ handled = FALSE;
+
+ if (!handled)
+ g_warning ("unhandled property '%s'", key);
+}
+
+static void
+port_properties_free (PortProperties *props)
+{
+ g_free (props->native_path);
+ g_free (props->adapter);
+ g_free (props->parent);
+ g_free (props);
+}
+
+static PortProperties *
+port_properties_get (DBusGConnection *bus,
+ const char *object_path)
+{
+ PortProperties *props;
+ GError *error;
+ GHashTable *hash_table;
+ DBusGProxy *prop_proxy;
+ const char *ifname = "org.freedesktop.DeviceKit.Disks.Port";
+
+ props = g_new0 (PortProperties, 1);
+
+ prop_proxy = dbus_g_proxy_new_for_name (bus,
+ "org.freedesktop.DeviceKit.Disks",
+ object_path,
+ "org.freedesktop.DBus.Properties");
+ error = NULL;
+ if (!dbus_g_proxy_call (prop_proxy,
+ "GetAll",
+ &error,
+ G_TYPE_STRING,
+ ifname,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ &hash_table,
+ G_TYPE_INVALID)) {
+ g_warning ("Couldn't call GetAll() to get properties for %s: %s", object_path, error->message);
+ g_error_free (error);
+
+ port_properties_free (props);
+ props = NULL;
+ goto out;
+ }
+
+ g_hash_table_foreach (hash_table, (GHFunc) collect_props, props);
+
+ g_hash_table_unref (hash_table);
+
+#if 0
+ g_print ("----------------------------------------------------------------------\n");
+ g_print ("native_path: %s\n", props->native_path);
+ g_print ("adapter: %s\n", props->adapter);
+ g_print ("parent: %s\n", props->parent);
+ g_print ("number: %d\n", props->number);
+#endif
+
+out:
+ g_object_unref (prop_proxy);
+ return props;
+}
+
+/* --- SUCKY CODE END --- */
+
+struct _GduPortPrivate
+{
+ DBusGConnection *bus;
+ DBusGProxy *proxy;
+ GduPool *pool;
+
+ char *object_path;
+
+ PortProperties *props;
+};
+
+enum {
+ CHANGED,
+ REMOVED,
+ LAST_SIGNAL,
+};
+
+static GObjectClass *parent_class = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GduPort, gdu_port, G_TYPE_OBJECT);
+
+GduPool *
+gdu_port_get_pool (GduPort *port)
+{
+ return g_object_ref (port->priv->pool);
+}
+
+static void
+gdu_port_finalize (GduPort *port)
+{
+ g_debug ("##### finalized port %s",
+ port->priv->props != NULL ? port->priv->props->native_path : port->priv->object_path);
+
+ dbus_g_connection_unref (port->priv->bus);
+ g_free (port->priv->object_path);
+ if (port->priv->proxy != NULL)
+ g_object_unref (port->priv->proxy);
+ if (port->priv->pool != NULL)
+ g_object_unref (port->priv->pool);
+ if (port->priv->props != NULL)
+ port_properties_free (port->priv->props);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (G_OBJECT (port));
+}
+
+static void
+gdu_port_class_init (GduPortClass *klass)
+{
+ GObjectClass *obj_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ obj_class->finalize = (GObjectFinalizeFunc) gdu_port_finalize;
+
+ g_type_class_add_private (klass, sizeof (GduPortPrivate));
+
+ signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GduPortClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[REMOVED] =
+ g_signal_new ("removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GduPortClass, removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+gdu_port_init (GduPort *port)
+{
+ port->priv = G_TYPE_INSTANCE_GET_PRIVATE (port, GDU_TYPE_PORT, GduPortPrivate);
+}
+
+static gboolean
+update_info (GduPort *port)
+{
+ PortProperties *new_properties;
+
+ new_properties = port_properties_get (port->priv->bus, port->priv->object_path);
+ if (new_properties != NULL) {
+ if (port->priv->props != NULL)
+ port_properties_free (port->priv->props);
+ port->priv->props = new_properties;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+GduPort *
+_gdu_port_new_from_object_path (GduPool *pool, const char *object_path)
+{
+ GError *error;
+ GduPort *port;
+
+ port = GDU_PORT (g_object_new (GDU_TYPE_PORT, NULL));
+ port->priv->object_path = g_strdup (object_path);
+ port->priv->pool = g_object_ref (pool);
+
+ error = NULL;
+ port->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (port->priv->bus == NULL) {
+ g_warning ("Couldn't connect to system bus: %s", error->message);
+ g_error_free (error);
+ goto error;
+ }
+
+ port->priv->proxy = dbus_g_proxy_new_for_name (port->priv->bus,
+ "org.freedesktop.DeviceKit.Disks",
+ port->priv->object_path,
+ "org.freedesktop.DeviceKit.Disks.Port");
+ dbus_g_proxy_set_default_timeout (port->priv->proxy, INT_MAX);
+ dbus_g_proxy_add_signal (port->priv->proxy, "Changed", G_TYPE_INVALID);
+
+ /* TODO: connect signals */
+
+ if (!update_info (port))
+ goto error;
+
+ g_debug ("_gdu_port_new_from_object_path: %s", port->priv->props->native_path);
+
+ return port;
+error:
+ g_object_unref (port);
+ return NULL;
+}
+
+gboolean
+_gdu_port_changed (GduPort *port)
+{
+ g_debug ("_gdu_port_changed: %s", port->priv->props->native_path);
+ if (update_info (port)) {
+ g_signal_emit (port, signals[CHANGED], 0);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+const gchar *
+gdu_port_get_object_path (GduPort *port)
+{
+ return port->priv->object_path;
+}
+
+
+const gchar *
+gdu_port_get_native_path (GduPort *port)
+{
+ return port->priv->props->native_path;
+}
+
+const gchar *
+gdu_port_get_adapter (GduPort *port)
+{
+ return port->priv->props->adapter;
+}
+
+const gchar *
+gdu_port_get_parent (GduPort *port)
+{
+ return port->priv->props->parent;
+}
+
+gint
+gdu_port_get_number (GduPort *port)
+{
+ return port->priv->props->number;
+}
diff --git a/src/gdu/gdu-port.h b/src/gdu/gdu-port.h
new file mode 100644
index 0000000..39c3ccc
--- /dev/null
+++ b/src/gdu/gdu-port.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* gdu-port.h
+ *
+ * Copyright (C) 2009 David Zeuthen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#if !defined (__GDU_INSIDE_GDU_H) && !defined (GDU_COMPILATION)
+#error "Only <gdu/gdu.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __GDU_PORT_H
+#define __GDU_PORT_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <gdu/gdu-types.h>
+#include <gdu/gdu-callbacks.h>
+
+G_BEGIN_DECLS
+
+#define GDU_TYPE_PORT (gdu_port_get_type ())
+#define GDU_PORT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDU_TYPE_PORT, GduPort))
+#define GDU_PORT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GDU_PORT, GduPortClass))
+#define GDU_IS_PORT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDU_TYPE_PORT))
+#define GDU_IS_PORT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDU_TYPE_PORT))
+#define GDU_PORT_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), GDU_TYPE_PORT, GduPortClass))
+
+typedef struct _GduPortClass GduPortClass;
+typedef struct _GduPortPrivate GduPortPrivate;
+
+struct _GduPort
+{
+ GObject parent;
+
+ /* private */
+ GduPortPrivate *priv;
+};
+
+struct _GduPortClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*changed) (GduPort *port);
+ void (*removed) (GduPort *port);
+};
+
+GType gdu_port_get_type (void);
+const char *gdu_port_get_object_path (GduPort *port);
+GduPool *gdu_port_get_pool (GduPort *port);
+
+const gchar *gdu_port_get_native_path (GduPort *port);
+const gchar *gdu_port_get_adapter (GduPort *port);
+const gchar *gdu_port_get_parent (GduPort *port);
+gint gdu_port_get_number (GduPort *port);
+
+G_END_DECLS
+
+#endif /* __GDU_ADAPTER_H */
diff --git a/src/gdu/gdu-private.h b/src/gdu/gdu-private.h
index cc9166e..52bc2f5 100644
--- a/src/gdu/gdu-private.h
+++ b/src/gdu/gdu-private.h
@@ -105,8 +105,11 @@ void _gdu_device_job_changed (GduDevice *device,
double job_percentage);
GduAdapter *_gdu_adapter_new_from_object_path (GduPool *pool, const char *object_path);
-gboolean _gdu_adapter_changed (GduAdapter *adapter);
-GduHba *_gdu_hba_new_from_adapter (GduPool *pool, GduAdapter *adapter);
+gboolean _gdu_adapter_changed (GduAdapter *adapter);
+GduHba *_gdu_hba_new_from_adapter (GduPool *pool, GduAdapter *adapter);
+
+GduPort *_gdu_port_new_from_object_path (GduPool *pool, const char *object_path);
+gboolean _gdu_port_changed (GduPort *port);
void _gdu_drive_rewrite_enclosing_presentable (GduDrive *drive);
void _gdu_volume_rewrite_enclosing_presentable (GduVolume *volume);
diff --git a/src/gdu/gdu-types.h b/src/gdu/gdu-types.h
index cc5ba70..96ede57 100644
--- a/src/gdu/gdu-types.h
+++ b/src/gdu/gdu-types.h
@@ -36,6 +36,7 @@ G_BEGIN_DECLS
typedef struct _GduPool GduPool;
typedef struct _GduDevice GduDevice;
typedef struct _GduAdapter GduAdapter;
+typedef struct _GduPort GduPort;
typedef struct _GduPresentable GduPresentable; /* Dummy typedef */
typedef struct _GduDrive GduDrive;
diff --git a/src/gdu/gdu.h b/src/gdu/gdu.h
index 656e8bb..7bd9dbc 100644
--- a/src/gdu/gdu.h
+++ b/src/gdu/gdu.h
@@ -32,6 +32,7 @@
#include <gdu/gdu-linux-md-drive.h>
#include <gdu/gdu-device.h>
#include <gdu/gdu-adapter.h>
+#include <gdu/gdu-port.h>
#include <gdu/gdu-drive.h>
#include <gdu/gdu-error.h>
#include <gdu/gdu-known-filesystem.h>
diff --git a/src/palimpsest/gdu-section-drive.c b/src/palimpsest/gdu-section-drive.c
index 0587487..42226cd 100644
--- a/src/palimpsest/gdu-section-drive.c
+++ b/src/palimpsest/gdu-section-drive.c
@@ -36,6 +36,8 @@ struct _GduSectionDrivePrivate
GduDetailsElement *firmware_element;
GduDetailsElement *serial_element;
GduDetailsElement *wwn_element;
+ GduDetailsElement *port_number_element;
+ GduDetailsElement *device_element;
GduDetailsElement *write_cache_element;
GduDetailsElement *rotation_rate_element;
GduDetailsElement *capacity_element;
@@ -102,6 +104,8 @@ gdu_section_drive_update (GduSection *_section)
guint rotation_rate;
gboolean is_rotational;
GIcon *icon;
+ const gchar *port_object_path;
+ GduPort *port;
gboolean show_cddvd_button;
gboolean show_format_button;
gboolean show_eject_button;
@@ -117,6 +121,7 @@ gdu_section_drive_update (GduSection *_section)
show_benchmark_button = FALSE;
d = NULL;
+ port = NULL;
wwn = NULL;
p = gdu_section_get_presentable (_section);
@@ -124,6 +129,30 @@ gdu_section_drive_update (GduSection *_section)
if (d == NULL)
goto out;
+ port_object_path = gdu_device_drive_get_port (d);
+ if (port_object_path != NULL && strlen (port_object_path) > 1) {
+ GduPool *pool;
+ pool = gdu_device_get_pool (d);
+ port = gdu_pool_get_port_by_object_path (pool, port_object_path);
+ g_object_unref (pool);
+ }
+ if (port != NULL) {
+ gint port_number;
+
+ port_number = gdu_port_get_number (port);
+ if (port_number >= 0) {
+ /* Start at 1 */
+ s = g_strdup_printf ("%d", port_number + 1);
+ gdu_details_element_set_text (section->priv->port_number_element, s);
+ g_free (s);
+ } else {
+ gdu_details_element_set_text (section->priv->port_number_element, "â??");
+ }
+ } else {
+ gdu_details_element_set_text (section->priv->port_number_element, "â??");
+ }
+ gdu_details_element_set_text (section->priv->device_element, gdu_device_get_device_file (d));
+
model = gdu_device_drive_get_model (d);
vendor = gdu_device_drive_get_vendor (d);
if (vendor != NULL && strlen (vendor) == 0)
@@ -595,6 +624,14 @@ gdu_section_drive_constructed (GObject *object)
g_ptr_array_add (elements, element);
section->priv->wwn_element = element;
+ element = gdu_details_element_new (_("Port Number:"), NULL, NULL);
+ g_ptr_array_add (elements, element);
+ section->priv->port_number_element = element;
+
+ element = gdu_details_element_new (_("Device:"), NULL, NULL);
+ g_ptr_array_add (elements, element);
+ section->priv->device_element = element;
+
element = gdu_details_element_new (_("Write Cache:"), NULL, NULL);
g_ptr_array_add (elements, element);
section->priv->write_cache_element = element;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]