From 5b6bae572f39a05e78f6c0c35018725f05c97a4d Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Tue, 5 Aug 2008 17:26:35 +0100 Subject: abstract out the client and client device parts of the devkit-power tool --- tools/Makefile.am | 4 + tools/dkp-client-device.c | 384 ++++++++++++++++++++++++++++++++++++++++++++++ tools/dkp-client-device.h | 72 +++++++++ tools/dkp-client.c | 269 ++++++++++++++++++++++++++++++++ tools/dkp-client.h | 66 ++++++++ tools/dkp-tool.c | 248 ++++-------------------------- 6 files changed, 829 insertions(+), 214 deletions(-) create mode 100644 tools/dkp-client-device.c create mode 100644 tools/dkp-client-device.h create mode 100644 tools/dkp-client.c create mode 100644 tools/dkp-client.h (limited to 'tools') diff --git a/tools/Makefile.am b/tools/Makefile.am index 6dfe157..6519c57 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -34,6 +34,10 @@ bin_PROGRAMS = devkit-power devkit-battery-power devkit_power_SOURCES = \ dkp-tool.c \ + dkp-client.c \ + dkp-client.h \ + dkp-client-device.c \ + dkp-client-device.h \ $(BUILT_SOURCES) devkit_power_CPPFLAGS = \ diff --git a/tools/dkp-client-device.c b/tools/dkp-client-device.c new file mode 100644 index 0000000..a3effc9 --- /dev/null +++ b/tools/dkp-client-device.c @@ -0,0 +1,384 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "dkp-debug.h" +#include "dkp-client-device.h" +#include "dkp-object.h" +#include "dkp-history-obj.h" + +static void dkp_client_device_class_init (DkpClientDeviceClass *klass); +static void dkp_client_device_init (DkpClientDevice *device); +static void dkp_client_device_finalize (GObject *object); + +#define DKP_CLIENT_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_TYPE_CLIENT_DEVICE, DkpClientDevicePrivate)) + +struct DkpClientDevicePrivate +{ + gchar *object_path; + DkpObject *obj; + DBusGConnection *bus; + DBusGProxy *proxy_source; + DBusGProxy *proxy_props; +}; + +enum { + DKP_CLIENT_DEVICE_CHANGED, + DKP_CLIENT_DEVICE_LAST_SIGNAL +}; + +static guint signals [DKP_CLIENT_DEVICE_LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (DkpClientDevice, dkp_client_device, G_TYPE_OBJECT) + +/** + * dkp_client_device_get_device_properties: + **/ +static GHashTable * +dkp_client_device_get_device_properties (DkpClientDevice *device) +{ + gboolean ret; + GError *error = NULL; + GHashTable *hash_table = NULL; + + ret = dbus_g_proxy_call (device->priv->proxy_props, "GetAll", &error, + G_TYPE_STRING, "org.freedesktop.DeviceKit.Power.Device", + G_TYPE_INVALID, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), + &hash_table, + G_TYPE_INVALID); + if (!ret) { + dkp_debug ("Couldn't call GetAll() to get properties for %s: %s", device->priv->object_path, error->message); + g_error_free (error); + goto out; + } +out: + return hash_table; +} + +/** + * dkp_client_device_refresh_internal: + **/ +static gboolean +dkp_client_device_refresh_internal (DkpClientDevice *device) +{ + GHashTable *hash; + + /* get all the properties */ + hash = dkp_client_device_get_device_properties (device); + if (hash == NULL) { + dkp_warning ("Cannot get device properties for %s", device->priv->object_path); + return FALSE; + } + dkp_object_set_from_map (device->priv->obj, hash); + g_hash_table_unref (hash); + return TRUE; +} + +/** + * dkp_client_device_changed_cb: + **/ +static void +dkp_client_device_changed_cb (DBusGProxy *proxy, DkpClientDevice *device) +{ + g_return_if_fail (DKP_IS_CLIENT_DEVICE (device)); + dkp_client_device_refresh_internal (device); + g_signal_emit (device, signals [DKP_CLIENT_DEVICE_CHANGED], 0, device->priv->obj); +} + +/** + * dkp_client_device_set_object_path: + **/ +gboolean +dkp_client_device_set_object_path (DkpClientDevice *device, const gchar *object_path) +{ + GError *error = NULL; + gboolean ret = FALSE; + DBusGProxy *proxy_source; + DBusGProxy *proxy_props; + + g_return_val_if_fail (DKP_IS_CLIENT_DEVICE (device), FALSE); + + if (device->priv->object_path != NULL) + return FALSE; + if (object_path == NULL) + return FALSE; + + /* connect to the bus */ + device->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (device->priv->bus == NULL) { + dkp_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + goto out; + } + + /* connect to the correct path for properties */ + proxy_props = dbus_g_proxy_new_for_name (device->priv->bus, "org.freedesktop.DeviceKit.Power", + object_path, "org.freedesktop.DBus.Properties"); + if (proxy_props == NULL) { + dkp_warning ("Couldn't connect to proxy"); + goto out; + } + + /* connect to the correct path for all the other methods */ + proxy_source = dbus_g_proxy_new_for_name (device->priv->bus, "org.freedesktop.DeviceKit.Power", + object_path, "org.freedesktop.DeviceKit.Power.Source"); + if (proxy_source == NULL) { + dkp_warning ("Couldn't connect to proxy"); + goto out; + } + + /* listen to Changed */ + dbus_g_proxy_add_signal (proxy_source, "Changed", G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxy_source, "Changed", + G_CALLBACK (dkp_client_device_changed_cb), device, NULL); + + /* yay */ + dkp_debug ("using object_path: %s", object_path); + device->priv->proxy_source = proxy_source; + device->priv->proxy_props = proxy_props; + device->priv->object_path = g_strdup (object_path); + + /* coldplug */ + ret = dkp_client_device_refresh_internal (device); + if (!ret) + dkp_warning ("cannot refresh"); +out: + return ret; +} + +/** + * dkp_client_device_get_object_path: + **/ +const gchar * +dkp_client_device_get_object_path (const DkpClientDevice *device) +{ + g_return_val_if_fail (DKP_IS_CLIENT_DEVICE (device), NULL); + return device->priv->object_path; +} + +/** + * dkp_client_device_get_object: + **/ +const DkpObject * +dkp_client_device_get_object (const DkpClientDevice *device) +{ + g_return_val_if_fail (DKP_IS_CLIENT_DEVICE (device), NULL); + return device->priv->obj; +} + +/** + * dkp_client_device_print: + **/ +gboolean +dkp_client_device_print (const DkpClientDevice *device) +{ + g_return_val_if_fail (DKP_IS_CLIENT_DEVICE (device), FALSE); + + /* print to screen */ + dkp_object_print (device->priv->obj); + + /* if we can, get stats */ + dkp_client_device_get_statistics (device, "charge", 120); + dkp_client_device_get_statistics (device, "rate", 120); + return TRUE; +} + +/** + * dkp_client_device_refresh: + **/ +gboolean +dkp_client_device_refresh (DkpClientDevice *device) +{ + GError *error = NULL; + gboolean ret; + + g_return_val_if_fail (DKP_IS_CLIENT_DEVICE (device), FALSE); + g_return_val_if_fail (device->priv->proxy_source != NULL, FALSE); + + /* just refresh the device */ + ret = dbus_g_proxy_call (device->priv->proxy_source, "Refresh", &error, + G_TYPE_INVALID, G_TYPE_INVALID); + if (!ret) { + dkp_debug ("Refresh() on %s failed: %s", device->priv->object_path, error->message); + g_error_free (error); + goto out; + } +out: + return ret; +} + +/** + * dkp_client_device_get_statistics: + * + * Returns an array of %DkpHistoryObj's + **/ +GPtrArray * +dkp_client_device_get_statistics (const DkpClientDevice *device, const gchar *type, guint timespec) +{ + GError *error = NULL; + GType g_type_gvalue_array; + GPtrArray *gvalue_ptr_array = NULL; + GValueArray *gva; + GValue *gv; + guint i; + DkpHistoryObj *obj; + GPtrArray *array = NULL; + gboolean ret; + + g_return_val_if_fail (DKP_IS_CLIENT_DEVICE (device), FALSE); + + g_type_gvalue_array = dbus_g_type_get_collection ("GPtrArray", + dbus_g_type_get_struct("GValueArray", + G_TYPE_UINT, + G_TYPE_DOUBLE, + G_TYPE_STRING, + G_TYPE_INVALID)); + + /* get compound data */ + ret = dbus_g_proxy_call (device->priv->proxy_source, "GetStatistics", &error, + G_TYPE_STRING, type, + G_TYPE_UINT, timespec, + G_TYPE_INVALID, + g_type_gvalue_array, &gvalue_ptr_array, + G_TYPE_INVALID); + if (!ret) { + dkp_debug ("GetStatistics(%s,%i) on %s failed: %s", type, timespec, + device->priv->object_path, error->message); + g_error_free (error); + goto out; + } + + /* no data */ + if (gvalue_ptr_array->len == 0) + goto out; + + /* convert */ + array = g_ptr_array_sized_new (gvalue_ptr_array->len); + for (i=0; ilen; i++) { + gva = (GValueArray *) g_ptr_array_index (gvalue_ptr_array, i); + obj = dkp_history_obj_new (); + /* 0 */ + gv = g_value_array_get_nth (gva, 0); + obj->time = g_value_get_uint (gv); + g_value_unset (gv); + /* 1 */ + gv = g_value_array_get_nth (gva, 1); + obj->value = g_value_get_double (gv); + g_value_unset (gv); + /* 2 */ + gv = g_value_array_get_nth (gva, 2); + obj->state = dkp_source_state_from_text (g_value_get_string (gv)); + g_value_unset (gv); + g_ptr_array_add (array, obj); + g_value_array_free (gva); + } + +out: + if (gvalue_ptr_array != NULL) + g_ptr_array_free (gvalue_ptr_array, TRUE); + return array; +} + +/** + * dkp_client_device_class_init: + * @klass: The DkpClientDeviceClass + **/ +static void +dkp_client_device_class_init (DkpClientDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = dkp_client_device_finalize; + + /** + * PkClient::changed: + * @device: the #DkpClientDevice instance that emitted the signal + * @obj: the #DkpObject that has changed + * + * The ::changed signal is emitted when the device data has changed. + **/ + signals [DKP_CLIENT_DEVICE_CHANGED] = + g_signal_new ("changed", + G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (DkpClientDeviceClass, changed), + NULL, NULL, g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + g_type_class_add_private (klass, sizeof (DkpClientDevicePrivate)); +} + +/** + * dkp_client_device_init: + * @client_device: This class instance + **/ +static void +dkp_client_device_init (DkpClientDevice *device) +{ + device->priv = DKP_CLIENT_DEVICE_GET_PRIVATE (device); + device->priv->object_path = NULL; + device->priv->proxy_source = NULL; + device->priv->proxy_props = NULL; + device->priv->obj = dkp_object_new (); +} + +/** + * dkp_client_device_finalize: + * @object: The object to finalize + **/ +static void +dkp_client_device_finalize (GObject *object) +{ + DkpClientDevice *device; + + g_return_if_fail (DKP_IS_CLIENT_DEVICE (object)); + + device = DKP_CLIENT_DEVICE (object); + + g_free (device->priv->object_path); + dkp_object_free (device->priv->obj); + if (device->priv->proxy_source != NULL) + g_object_unref (device->priv->proxy_source); + if (device->priv->proxy_props != NULL) + g_object_unref (device->priv->proxy_props); + dbus_g_connection_unref (device->priv->bus); + + G_OBJECT_CLASS (dkp_client_device_parent_class)->finalize (object); +} + +/** + * dkp_client_device_new: + * + * Return value: a new DkpClientDevice object. + **/ +DkpClientDevice * +dkp_client_device_new (void) +{ + DkpClientDevice *device; + device = g_object_new (DKP_TYPE_CLIENT_DEVICE, NULL); + return DKP_CLIENT_DEVICE (device); +} + diff --git a/tools/dkp-client-device.h b/tools/dkp-client-device.h new file mode 100644 index 0000000..646d4f6 --- /dev/null +++ b/tools/dkp-client-device.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __DKP_CLIENT_DEVICE_H +#define __DKP_CLIENT_DEVICE_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define DKP_TYPE_CLIENT_DEVICE (dkp_client_device_get_type ()) +#define DKP_CLIENT_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_TYPE_CLIENT_DEVICE, DkpClientDevice)) +#define DKP_CLIENT_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_TYPE_CLIENT_DEVICE, DkpClientDeviceClass)) +#define DKP_IS_CLIENT_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_TYPE_CLIENT_DEVICE)) +#define DKP_IS_CLIENT_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_TYPE_CLIENT_DEVICE)) +#define DKP_CLIENT_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_CLIENT_DEVICE, DkpClientDeviceClass)) +#define DKP_CLIENT_DEVICE_ERROR (dkp_client_device_error_quark ()) +#define DKP_CLIENT_DEVICE_TYPE_ERROR (dkp_client_device_error_get_type ()) + +typedef struct DkpClientDevicePrivate DkpClientDevicePrivate; + +typedef struct +{ + GObject parent; + DkpClientDevicePrivate *priv; +} DkpClientDevice; + +typedef struct +{ + GObjectClass parent_class; + void (*changed) (DkpClientDevice *device, + const DkpObject *obj); +} DkpClientDeviceClass; + +GType dkp_client_device_get_type (void) G_GNUC_CONST; +DkpClientDevice *dkp_client_device_new (void); + +const DkpObject *dkp_client_device_get_object (const DkpClientDevice *device); +const gchar *dkp_client_device_get_object_path (const DkpClientDevice *device); +gboolean dkp_client_device_set_object_path (DkpClientDevice *device, + const gchar *object_path); + +gboolean dkp_client_device_print (const DkpClientDevice *device); +gboolean dkp_client_device_refresh (DkpClientDevice *device); +GPtrArray *dkp_client_device_get_statistics (const DkpClientDevice *device, + const gchar *type, + guint timespec); + +G_END_DECLS + +#endif /* __DKP_CLIENT_DEVICE_H */ + diff --git a/tools/dkp-client.c b/tools/dkp-client.c new file mode 100644 index 0000000..c72c433 --- /dev/null +++ b/tools/dkp-client.c @@ -0,0 +1,269 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "dkp-debug.h" +#include "dkp-client.h" +#include "dkp-client-device.h" + +static void dkp_client_class_init (DkpClientClass *klass); +static void dkp_client_init (DkpClient *client); +static void dkp_client_finalize (GObject *object); + +#define DKP_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_TYPE_CLIENT, DkpClientPrivate)) + +struct DkpClientPrivate +{ + DBusGConnection *bus; + DBusGProxy *proxy; + GHashTable *hash; + GPtrArray *array; +}; + +enum { + DKP_CLIENT_ADDED, + DKP_CLIENT_CHANGED, + DKP_CLIENT_REMOVED, + DKP_CLIENT_LAST_SIGNAL +}; + +static guint signals [DKP_CLIENT_LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (DkpClient, dkp_client, G_TYPE_OBJECT) + +/** + * dkp_client_get_device: + **/ +static DkpClientDevice * +dkp_client_get_device (DkpClient *client, const gchar *object_path) +{ + DkpClientDevice *device; + device = g_hash_table_lookup (client->priv->hash, object_path); + return device; +} + +/** + * dkp_client_enumerate_devices: + **/ +GPtrArray * +dkp_client_enumerate_devices (const DkpClient *client) +{ + gboolean ret; + GError *error = NULL; + GPtrArray *devices = NULL; + GType g_type_array; + + g_type_array = dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH); + ret = dbus_g_proxy_call (client->priv->proxy, "EnumerateDevices", &error, + G_TYPE_INVALID, + g_type_array, &devices, + G_TYPE_INVALID); + if (!ret) { + dkp_warning ("Couldn't enumerate devices: %s", error->message); + g_error_free (error); + } + return devices; +} + +/** + * dkp_client_add: + **/ +static DkpClientDevice * +dkp_client_add (DkpClient *client, const gchar *object_path) +{ + DkpClientDevice *device; + + /* create new device */ + device = dkp_client_device_new (); + dkp_client_device_set_object_path (device, object_path); + + g_ptr_array_add (client->priv->array, device); + g_hash_table_insert (client->priv->hash, g_strdup (object_path), device); + return device; +} + +/** + * dkp_client_remove: + **/ +static gboolean +dkp_client_remove (DkpClient *client, DkpClientDevice *device) +{ + /* deallocate it */ + g_object_unref (device); + + g_ptr_array_remove (client->priv->array, device); + g_hash_table_remove (client->priv->hash, device); + return TRUE; +} + +/** + * dkp_client_added_cb: + **/ +static void +dkp_client_added_cb (DBusGProxy *proxy, const gchar *object_path, DkpClient *client) +{ + DkpClientDevice *device; + + /* create new device */ + device = dkp_client_add (client, object_path); + g_signal_emit (device, signals [DKP_CLIENT_ADDED], 0, device); +} + +/** + * dkp_client_changed_cb: + **/ +static void +dkp_client_changed_cb (DBusGProxy *proxy, const gchar *object_path, DkpClient *client) +{ + DkpClientDevice *device; + device = dkp_client_get_device (client, object_path); + if (device != NULL) + g_signal_emit (device, signals [DKP_CLIENT_CHANGED], 0, device); +} + +/** + * dkp_client_removed_cb: + **/ +static void +dkp_client_removed_cb (DBusGProxy *proxy, const gchar *object_path, DkpClient *client) +{ + DkpClientDevice *device; + device = dkp_client_get_device (client, object_path); + if (device != NULL) + g_signal_emit (device, signals [DKP_CLIENT_REMOVED], 0, device); + dkp_client_remove (client, device); +} + +/** + * dkp_client_class_init: + * @klass: The DkpClientClass + **/ +static void +dkp_client_class_init (DkpClientClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = dkp_client_finalize; + g_type_class_add_private (klass, sizeof (DkpClientPrivate)); +} + +/** + * dkp_client_init: + * @client: This class instance + **/ +static void +dkp_client_init (DkpClient *client) +{ + GError *error = NULL; + const gchar *object_path; + GPtrArray *devices; + guint i; + + client->priv = DKP_CLIENT_GET_PRIVATE (client); + client->priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + client->priv->array = g_ptr_array_new (); + + /* get on the bus */ + client->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (client->priv->bus == NULL) { + dkp_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + goto out; + } + + /* connect to main interface */ + client->priv->proxy = dbus_g_proxy_new_for_name (client->priv->bus, "org.freedesktop.DeviceKit.Power", + "/", "org.freedesktop.DeviceKit.Power"); + if (client->priv->proxy == NULL) { + dkp_warning ("Couldn't connect to proxy"); + goto out; + } + + dbus_g_proxy_add_signal (client->priv->proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_add_signal (client->priv->proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_add_signal (client->priv->proxy, "DeviceChanged", G_TYPE_STRING, G_TYPE_INVALID); + + /* all callbacks */ + dbus_g_proxy_connect_signal (client->priv->proxy, "DeviceAdded", + G_CALLBACK (dkp_client_added_cb), client, NULL); + dbus_g_proxy_connect_signal (client->priv->proxy, "DeviceRemoved", + G_CALLBACK (dkp_client_removed_cb), client, NULL); + dbus_g_proxy_connect_signal (client->priv->proxy, "DeviceChanged", + G_CALLBACK (dkp_client_changed_cb), client, NULL); + + /* coldplug */ + devices = dkp_client_enumerate_devices (client); + if (devices == NULL) + goto out; + for (i=0; ilen; i++) { + object_path = (const gchar *) g_ptr_array_index (devices, i); + dkp_client_add (client, object_path); + } +out: + return; +} + +/** + * dkp_client_finalize: + * @object: The object to finalize + **/ +static void +dkp_client_finalize (GObject *object) +{ + DkpClient *client; + DkpClientDevice *device; + guint i; + + g_return_if_fail (DKP_IS_CLIENT (object)); + + client = DKP_CLIENT (object); + + /* free any devices */ + for (i=0; ipriv->array->len; i++) { + device = (DkpClientDevice *) g_ptr_array_index (client->priv->array, i); + dkp_client_remove (client, device); + } + + g_ptr_array_free (client->priv->array, TRUE); + g_hash_table_unref (client->priv->hash); + dbus_g_connection_unref (client->priv->bus); + + G_OBJECT_CLASS (dkp_client_parent_class)->finalize (object); +} + +/** + * dkp_client_new: + * + * Return value: a new DkpClient object. + **/ +DkpClient * +dkp_client_new (void) +{ + DkpClient *client; + client = g_object_new (DKP_TYPE_CLIENT, NULL); + return DKP_CLIENT (client); +} + diff --git a/tools/dkp-client.h b/tools/dkp-client.h new file mode 100644 index 0000000..5c9fb61 --- /dev/null +++ b/tools/dkp-client.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __DKP_CLIENT_H +#define __DKP_CLIENT_H + +#include +#include +#include "dkp-client-device.h" + +G_BEGIN_DECLS + +#define DKP_TYPE_CLIENT (dkp_client_get_type ()) +#define DKP_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_TYPE_CLIENT, DkpClient)) +#define DKP_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_TYPE_CLIENT, DkpClientClass)) +#define DKP_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_TYPE_CLIENT)) +#define DKP_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_TYPE_CLIENT)) +#define DKP_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_CLIENT, DkpClientClass)) +#define DKP_CLIENT_ERROR (dkp_client_error_quark ()) +#define DKP_CLIENT_TYPE_ERROR (dkp_client_error_get_type ()) + +typedef struct DkpClientPrivate DkpClientPrivate; + +typedef struct +{ + GObject parent; + DkpClientPrivate *priv; +} DkpClient; + +typedef struct +{ + GObjectClass parent_class; + void (*added) (DkpClient *client, + const DkpClientDevice *device); + void (*changed) (DkpClient *client, + const DkpClientDevice *device); + void (*removed) (DkpClient *client, + const DkpClientDevice *device); +} DkpClientClass; + +GType dkp_client_get_type (void) G_GNUC_CONST; +DkpClient *dkp_client_new (void); +GPtrArray *dkp_client_enumerate_devices (const DkpClient *client); + +G_END_DECLS + +#endif /* __DKP_CLIENT_H */ + diff --git a/tools/dkp-tool.c b/tools/dkp-tool.c index 9c46e0a..53274a1 100644 --- a/tools/dkp-tool.c +++ b/tools/dkp-tool.c @@ -50,8 +50,9 @@ #include "dkp-object.h" #include "dkp-history-obj.h" -static DBusGConnection *bus = NULL; -static DBusGProxy *power_proxy = NULL; +#include "dkp-client.h" +#include "dkp-client-device.h" + static GMainLoop *loop; static gboolean opt_enumerate = FALSE; @@ -59,19 +60,15 @@ static gboolean opt_monitor = FALSE; static gboolean opt_monitor_detail = FALSE; static gchar *opt_show_info = FALSE; -static gboolean dkp_tool_do_monitor (void); -static void dkp_tool_show_device_info (const gchar *object_path); - /** * dkp_tool_device_added_cb: **/ static void -dkp_tool_device_added_cb (DBusGProxy *proxy, const gchar *object_path, gpointer user_data) +dkp_tool_device_added_cb (DkpClient *client, const DkpClientDevice *device, gpointer user_data) { - g_print ("added: %s\n", object_path); + g_print ("added: %s\n", dkp_client_device_get_object_path (device)); if (opt_monitor_detail) { - dkp_tool_show_device_info (object_path); - g_print ("\n"); + dkp_client_device_print (device); } } @@ -79,13 +76,12 @@ dkp_tool_device_added_cb (DBusGProxy *proxy, const gchar *object_path, gpointer * dkp_tool_device_changed_cb: **/ static void -dkp_tool_device_changed_cb (DBusGProxy *proxy, const gchar *object_path, gpointer user_data) +dkp_tool_device_changed_cb (DkpClient *client, const DkpClientDevice *device, gpointer user_data) { - g_print ("changed: %s\n", object_path); + g_print ("changed: %s\n", dkp_client_device_get_object_path (device)); if (opt_monitor_detail) { /* TODO: would be nice to just show the diff */ - dkp_tool_show_device_info (object_path); - g_print ("\n"); + dkp_client_device_print (device); } } @@ -93,195 +89,28 @@ dkp_tool_device_changed_cb (DBusGProxy *proxy, const gchar *object_path, gpointe * dkp_tool_device_removed_cb: **/ static void -dkp_tool_device_removed_cb (DBusGProxy *proxy, const gchar *object_path, gpointer user_data) -{ - g_print ("removed: %s\n", object_path); -} - -/** - * dkp_tool_get_device_properties: - **/ -static GHashTable * -dkp_tool_get_device_properties (DBusGConnection *bus, const char *object_path) +dkp_tool_device_removed_cb (DkpClient *client, const DkpClientDevice *device, gpointer user_data) { - GError *error; - GHashTable *hash_table = NULL; - DBusGProxy *proxy; - const char *ifname = "org.freedesktop.DeviceKit.Power.Device"; - - proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DeviceKit.Power", - object_path, "org.freedesktop.DBus.Properties"); - error = NULL; - if (!dbus_g_proxy_call (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)) { - dkp_debug ("Couldn't call GetAll() to get properties for %s: %s", object_path, error->message); - g_error_free (error); - goto out; - } - -out: - g_object_unref (proxy); - return hash_table; + g_print ("removed: %s\n", dkp_client_device_get_object_path (device)); } /** * dkp_tool_do_monitor: **/ static gboolean -dkp_tool_do_monitor (void) +dkp_tool_do_monitor (DkpClient *client) { g_print ("Monitoring activity from the power daemon. Press Ctrl+C to cancel.\n"); - dbus_g_proxy_connect_signal (power_proxy, "DeviceAdded", - G_CALLBACK (dkp_tool_device_added_cb), NULL, NULL); - dbus_g_proxy_connect_signal (power_proxy, "DeviceRemoved", - G_CALLBACK (dkp_tool_device_removed_cb), NULL, NULL); - dbus_g_proxy_connect_signal (power_proxy, "DeviceChanged", - G_CALLBACK (dkp_tool_device_changed_cb), NULL, NULL); + g_signal_connect (client, "added", G_CALLBACK (dkp_tool_device_added_cb), NULL); + g_signal_connect (client, "removed", G_CALLBACK (dkp_tool_device_removed_cb), NULL); + g_signal_connect (client, "changed", G_CALLBACK (dkp_tool_device_changed_cb), NULL); + g_main_loop_run (loop); return FALSE; } -/** - * dkp_tool_get_device_stats: - **/ -static gboolean -dkp_tool_get_device_stats (DBusGConnection *bus, const char *object_path, const gchar *type, guint timespec) -{ - GError *error = NULL; - DBusGProxy *proxy; - GType g_type_gvalue_array; - GPtrArray *gvalue_ptr_array = NULL; - GValueArray *gva; - GValue *gv; - guint i; - DkpHistoryObj *obj; - GPtrArray *array; - gboolean ret; - - proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DeviceKit.Power", - object_path, "org.freedesktop.DeviceKit.Power.Source"); - - g_type_gvalue_array = dbus_g_type_get_collection ("GPtrArray", - dbus_g_type_get_struct("GValueArray", - G_TYPE_UINT, - G_TYPE_DOUBLE, - G_TYPE_STRING, - G_TYPE_INVALID)); - - /* get compound data */ - ret = dbus_g_proxy_call (proxy, "GetStatistics", &error, - G_TYPE_STRING, type, - G_TYPE_UINT, timespec, - G_TYPE_INVALID, - g_type_gvalue_array, &gvalue_ptr_array, - G_TYPE_INVALID); - if (!ret) { - dkp_debug ("GetStatistics(%s,%i) on %s failed: %s", type, timespec, object_path, error->message); - g_error_free (error); - goto out; - } - - /* no data */ - if (gvalue_ptr_array->len == 0) - goto out; - - /* convert */ - array = g_ptr_array_sized_new (gvalue_ptr_array->len); - for (i=0; ilen; i++) { - gva = (GValueArray *) g_ptr_array_index (gvalue_ptr_array, i); - obj = dkp_history_obj_new (); - /* 0 */ - gv = g_value_array_get_nth (gva, 0); - obj->time = g_value_get_uint (gv); - g_value_unset (gv); - /* 1 */ - gv = g_value_array_get_nth (gva, 1); - obj->value = g_value_get_double (gv); - g_value_unset (gv); - /* 2 */ - gv = g_value_array_get_nth (gva, 2); - obj->state = dkp_source_state_from_text (g_value_get_string (gv)); - g_value_unset (gv); - g_ptr_array_add (array, obj); - g_value_array_free (gva); - } - - /* print */ - g_print (" statistics (%s)\n", type); - for (i=0; ilen; i++) { - obj = (DkpHistoryObj *) g_ptr_array_index (array, i); - g_print (" %lu seconds\t%.2lf (%s)\n", time (NULL) - obj->time, obj->value, dkp_source_state_to_text (obj->state)); - } - g_ptr_array_free (array, TRUE); - -out: - if (gvalue_ptr_array != NULL) - g_ptr_array_free (gvalue_ptr_array, TRUE); - g_object_unref (proxy); - return TRUE; -} - -/** - * dkp_tool_show_device_info: - **/ -static void -dkp_tool_show_device_info (const gchar *object_path) -{ - GHashTable *hash; - DkpObject *obj; - - /* get all the properties */ - hash = dkp_tool_get_device_properties (bus, object_path); - if (hash == NULL) { - g_print ("Cannot get device properties for %s\n", object_path); - return; - } - - /* create an object and copy properties */ - obj = dkp_object_new (); - dkp_object_set_from_map (obj, hash); - - /* print to screen */ - dkp_object_print (obj); - - /* if we can, get stats */ - dkp_tool_get_device_stats (bus, object_path, "charge", 120); - dkp_tool_get_device_stats (bus, object_path, "rate", 120); - - /* tidy up */ - dkp_object_free (obj); - g_hash_table_unref (hash); -} - -/** - * dkp_tool_enumerate_devices: - **/ -static GPtrArray * -dkp_tool_enumerate_devices (DBusGProxy *proxy) -{ - gboolean ret; - GError *error = NULL; - GPtrArray *devices = NULL; - GType g_type_array; - - g_type_array = dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH); - ret = dbus_g_proxy_call (proxy, "EnumerateDevices", &error, - G_TYPE_INVALID, - g_type_array, &devices, - G_TYPE_INVALID); - if (!ret) { - dkp_warning ("Couldn't enumerate devices: %s", error->message); - g_error_free (error); - } - return devices; -} - /** * main: **/ @@ -290,18 +119,20 @@ main (int argc, char **argv) { int ret = 1; GOptionContext *context; - GError *error = NULL; gboolean verbose = FALSE; gboolean opt_dump = FALSE; unsigned int n; + DkpClient *client; + DkpClientDevice *device; + const GOptionEntry entries[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, _("Show extra debugging information"), NULL }, { "enumerate", 'e', 0, G_OPTION_ARG_NONE, &opt_enumerate, _("Enumerate objects paths for devices"), NULL }, - { "dump", 0, 0, G_OPTION_ARG_NONE, &opt_dump, _("Dump all parameters for all objects"), NULL }, - { "monitor", 0, 0, G_OPTION_ARG_NONE, &opt_monitor, _("Monitor activity from the power daemon"), NULL }, + { "dump", 'd', 0, G_OPTION_ARG_NONE, &opt_dump, _("Dump all parameters for all objects"), NULL }, + { "monitor", 'm', 0, G_OPTION_ARG_NONE, &opt_monitor, _("Monitor activity from the power daemon"), NULL }, { "monitor-detail", 0, 0, G_OPTION_ARG_NONE, &opt_monitor_detail, _("Monitor with detail"), NULL }, - { "show-info", 0, 0, G_OPTION_ARG_STRING, &opt_show_info, _("Show information about object path"), NULL }, + { "show-info", 'i', 0, G_OPTION_ARG_STRING, &opt_show_info, _("Show information about object path"), NULL }, { NULL } }; @@ -314,24 +145,12 @@ main (int argc, char **argv) dkp_debug_init (verbose); loop = g_main_loop_new (NULL, FALSE); - - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (bus == NULL) { - dkp_warning ("Couldn't connect to system bus: %s", error->message); - g_error_free (error); - goto out; - } - - power_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DeviceKit.Power", - "/", "org.freedesktop.DeviceKit.Power"); - dbus_g_proxy_add_signal (power_proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_add_signal (power_proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_add_signal (power_proxy, "DeviceChanged", G_TYPE_STRING, G_TYPE_INVALID); + client = dkp_client_new (); if (opt_enumerate || opt_dump) { GPtrArray *devices; const gchar *object_path; - devices = dkp_tool_enumerate_devices (power_proxy); + devices = dkp_client_enumerate_devices (client); if (devices == NULL) goto out; for (n=0; n < devices->len; n++) { @@ -340,25 +159,26 @@ main (int argc, char **argv) g_print ("%s\n", object_path); else { g_print ("Device: %s\n", object_path); - dkp_tool_show_device_info (object_path); + device = dkp_client_device_new (); + dkp_client_device_set_object_path (device, object_path); + dkp_client_device_print (device); + g_object_unref (device); } } g_ptr_array_foreach (devices, (GFunc) g_free, NULL); g_ptr_array_free (devices, TRUE); } else if (opt_monitor || opt_monitor_detail) { - if (!dkp_tool_do_monitor ()) + if (!dkp_tool_do_monitor (client)) goto out; } else if (opt_show_info != NULL) { - dkp_tool_show_device_info (opt_show_info); + device = dkp_client_device_new (); + dkp_client_device_set_object_path (device, opt_show_info); + dkp_client_device_print (device); + g_object_unref (device); } ret = 0; - out: - if (power_proxy != NULL) - g_object_unref (power_proxy); - if (bus != NULL) - dbus_g_connection_unref (bus); - + g_object_unref (client); return ret; } -- cgit v1.2.1