diff options
Diffstat (limited to 'libindicator/indicator-service-manager.c')
-rw-r--r-- | libindicator/indicator-service-manager.c | 134 |
1 files changed, 118 insertions, 16 deletions
diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index b4d5915..69b1343 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -1,3 +1,26 @@ +/* +An object used to manage services. Either start them or +just connect to them. + +Copyright 2009 Canonical Ltd. + +Authors: + Ted Gould <ted@canonical.com> + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 3.0 as published by the Free Software Foundation. + +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 General Public License version 3.0 for more details. + +You should have received a copy of the GNU General Public +License along with this library. If not, see +<http://www.gnu.org/licenses/>. +*/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -10,6 +33,15 @@ #include "dbus-shared.h" /* Private Stuff */ +/** + IndicatorServiceManagerPrivate: + @name: The well known dbus name the service should be on. + @dbus_proxy: A proxy to talk to the dbus daemon. + @service_proxy: The proxy to the service itself. + @connected: Whether we're connected to the service or not. + @this_service_version: The version of the service that we're looking for. + @bus: A reference to the bus so we don't have to keep getting it. +*/ typedef struct _IndicatorServiceManagerPrivate IndicatorServiceManagerPrivate; struct _IndicatorServiceManagerPrivate { gchar * name; @@ -58,6 +90,8 @@ static void start_service (IndicatorServiceManager * service); G_DEFINE_TYPE (IndicatorServiceManager, indicator_service_manager, G_TYPE_OBJECT); +/* Build all of our signals and proxies and tie everything + all together. Lovely. */ static void indicator_service_manager_class_init (IndicatorServiceManagerClass *klass) { @@ -105,6 +139,9 @@ indicator_service_manager_class_init (IndicatorServiceManagerClass *klass) return; } +/* This inits all the variable and sets up the proxy + to dbus. It doesn't look for the service as at this + point we don't know it's name. */ static void indicator_service_manager_init (IndicatorServiceManager *self) { @@ -141,6 +178,10 @@ indicator_service_manager_init (IndicatorServiceManager *self) return; } +/* If we're connected this provides all the signals to say + that we're about to not be. Then it takes down the proxies + and tells the service that we're not interested in being + its friend anymore either. */ static void indicator_service_manager_dispose (GObject *object) { @@ -176,6 +217,7 @@ indicator_service_manager_dispose (GObject *object) return; } +/* Ironically, we don't allocate a lot of memory ourselves. */ static void indicator_service_manager_finalize (GObject *object) { @@ -190,6 +232,8 @@ indicator_service_manager_finalize (GObject *object) return; } +/* Either copies the name into the private variable or + sets the version. Do it wrong and it'll get upset. */ static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { @@ -202,16 +246,12 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec switch (prop_id) { /* *********************** */ case PROP_NAME: - if (G_VALUE_HOLDS_STRING(value)) { - if (priv->name != NULL) { - g_error("Name can not be set twice!"); - return; - } - priv->name = g_value_dup_string(value); - start_service(self); - } else { - g_warning("Name is a string bud."); + if (priv->name != NULL) { + g_error("Name can not be set twice!"); + return; } + priv->name = g_value_dup_string(value); + start_service(self); break; /* *********************** */ case PROP_VERSION: @@ -226,6 +266,8 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec return; } +/* Grabs the values from the private variables and + puts them into the value. */ static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { @@ -238,11 +280,7 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe switch (prop_id) { /* *********************** */ case PROP_NAME: - if (G_VALUE_HOLDS_STRING(value)) { - g_value_set_string(value, priv->name); - } else { - g_warning("Name is a string bud."); - } + g_value_set_string(value, priv->name); break; /* *********************** */ case PROP_VERSION: @@ -257,6 +295,12 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe return; } +/* A callback from telling a service that we want to watch + it. It gives us the service API version and the version + of the other APIs it supports. We check both of those. + If they don't match then we unwatch it. Otherwise, we + signal a connection change to tell the rest of the world + that we have a service now. */ static void watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_version, GError * error, gpointer user_data) { @@ -288,6 +332,10 @@ watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_vers return; } +/* The callback after asking the dbus-daemon to start a + service for us. It can return success or failure, on + failure we can't do much. But, with sucess, we start + to build a proxy and tell the service that we're watching. */ static void start_service_cb (DBusGProxy * proxy, guint status, GError * error, gpointer user_data) { @@ -318,6 +366,10 @@ start_service_cb (DBusGProxy * proxy, guint status, GError * error, gpointer use return; } +/* The function that handles getting us connected to the service. + In many cases it will start the service, but if the service + is already there it just allocates the service proxy and acts + like it was no big deal. */ static void start_service (IndicatorServiceManager * service) { @@ -343,6 +395,8 @@ start_service (IndicatorServiceManager * service) start_service_cb, service); } else { + g_object_add_weak_pointer(G_OBJECT(priv->service_proxy), (gpointer *)&(priv->service_proxy)); + /* If we got a proxy just because we're good people then we need to call watch on it just like 'start_service_cb' does. */ @@ -355,6 +409,19 @@ start_service (IndicatorServiceManager * service) } /* API */ + +/** + indicator_service_manager_new: + @dbus_name: The well known name of the service on DBus + + This creates a new service manager object. If the service + is not running it will start it. No matter what, it will + give a IndicatorServiceManager::connection-changed event + signal when it gets connected. + + Return value: A brand new lovely #IndicatorServiceManager + object. +*/ IndicatorServiceManager * indicator_service_manager_new (gchar * dbus_name) { @@ -365,6 +432,20 @@ indicator_service_manager_new (gchar * dbus_name) return INDICATOR_SERVICE_MANAGER(obj); } +/** + inicator_service_manager_new_version: + @dbus_name: The well known name of the service on DBus + @version: Version of the service we expect + + This creates a new service manager object. It also sets + the version of the service that we're expecting to see. + In general, it behaves similarly to #indicator_service_manager_new() + except that it checks @version against the version returned + by the service. + + Return value: A brand new lovely #IndicatorServiceManager + object. +*/ IndicatorServiceManager * indicator_service_manager_new_version (gchar * dbus_name, guint version) { @@ -376,13 +457,34 @@ indicator_service_manager_new_version (gchar * dbus_name, guint version) return INDICATOR_SERVICE_MANAGER(obj); } +/** + indicator_service_manager_connected: + @sm: #IndicatorServiceManager object to check + + Checks to see if the service manager is connected to a + service. + + Return value: #TRUE if there is a service connceted. +*/ gboolean indicator_service_manager_connected (IndicatorServiceManager * sm) { - - return FALSE; + g_return_val_if_fail(INDICATOR_IS_SERVICE_MANAGER(sm), FALSE); + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(sm); + return priv->connected; } +/** + indicator_service_manager_set_refresh: + @sm: #IndicatorServiceManager object to configure + @time_in_ms: The refresh time in milliseconds + + Use this function to set the amount of time between restarting + services that may crash or shutdown. This is mostly useful + for testing and development. + + NOTE: Not yet implemented. +*/ void indicator_service_manager_set_refresh (IndicatorServiceManager * sm, guint time_in_ms) { |