diff options
Diffstat (limited to 'libindicator')
-rw-r--r-- | libindicator/indicator-service-manager.c | 134 | ||||
-rw-r--r-- | libindicator/indicator-service-manager.h | 23 | ||||
-rw-r--r-- | libindicator/indicator-service.c | 62 | ||||
-rw-r--r-- | libindicator/indicator-service.h | 23 |
4 files changed, 225 insertions, 17 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) { diff --git a/libindicator/indicator-service-manager.h b/libindicator/indicator-service-manager.h index 65a93ea..bf6d1b0 100644 --- a/libindicator/indicator-service-manager.h +++ b/libindicator/indicator-service-manager.h @@ -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/>. +*/ + #ifndef __INDICATOR_SERVICE_MANAGER_H__ #define __INDICATOR_SERVICE_MANAGER_H__ diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index 89842bb..e2ec6b2 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -1,3 +1,26 @@ +/* +An object used to provide a simple interface for a service +to query version and manage whether it's running. + +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 @@ -14,8 +37,16 @@ static gboolean _indicator_service_server_un_watch (IndicatorService * service, #include "dbus-shared.h" /* Private Stuff */ +/** + IndicatorSevicePrivate: + @name: The DBus well known name for the service. + @dbus_proxy: A proxy for talking to the dbus bus manager. + @timeout: The source ID for the timeout event. + @watcher: A list of processes on dbus that are watching us. + @this_service_version: The version to hand out that we're + implementing. May not be set, so we'll send zero (default). +*/ typedef struct _IndicatorServicePrivate IndicatorServicePrivate; - struct _IndicatorServicePrivate { gchar * name; DBusGProxy * dbus_proxy; @@ -113,6 +144,10 @@ indicator_service_class_init (IndicatorServiceClass *klass) return; } +/* This function builds the variables, sets up the dbus + proxy and registers the object on dbus. Importantly, + it does not request a name as we don't know what name + we have yet. */ static void indicator_service_init (IndicatorService *self) { @@ -162,6 +197,8 @@ indicator_service_init (IndicatorService *self) return; } +/* Unrefcounting the proxies and making sure that our + timeout doesn't come to haunt us. */ static void indicator_service_dispose (GObject *object) { @@ -181,6 +218,8 @@ indicator_service_dispose (GObject *object) return; } +/* Freeing the name we're looking for and all of the + information on the watchers we're tracking. */ static void indicator_service_finalize (GObject *object) { @@ -200,6 +239,8 @@ indicator_service_finalize (GObject *object) return; } +/* Either copies a string for the name or it just grabs + the value of the version. */ static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { @@ -236,6 +277,8 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec return; } +/* Copies out the name into a value or the version number. + Probably this is the least useful code in this file. */ static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { @@ -267,6 +310,9 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe return; } +/* This is the function that gets executed if we timeout + because there are no watchers. We sent the shutdown + signal and hope someone does something sane with it. */ static gboolean timeout_no_watchers (gpointer data) { @@ -274,6 +320,9 @@ timeout_no_watchers (gpointer data) return FALSE; } +/* The callback from our request to get a well known name + on dbus. If we can't get it we send the shutdown signal. + Else we start the timer to see if anyone cares about us. */ static void try_and_get_name_cb (DBusGProxy * proxy, guint status, GError * error, gpointer data) { @@ -294,6 +343,7 @@ try_and_get_name_cb (DBusGProxy * proxy, guint status, GError * error, gpointer return; } +/* This function sets up the request for the name on dbus. */ static void try_and_get_name (IndicatorService * service) { @@ -310,6 +360,10 @@ try_and_get_name (IndicatorService * service) return; } +/* Here is the function that gets called by the dbus + interface "Watch" function. It is an async function so + that we can get the sender and store that information. We + put them in a list and reset the timeout. */ static gboolean _indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocation * method) { @@ -328,12 +382,18 @@ _indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocati return TRUE; } +/* Mung g_strcmp0 into GCompareFunc */ static gint find_watcher (gconstpointer a, gconstpointer b) { return g_strcmp0((const gchar *)a, (const gchar *)b); } +/* A function connecting into the dbus interface for the + "UnWatch" function. It is also an async function to get + the sender. It then looks the sender up and removes them + from the list of watchers. If there are none left, it then + starts the timer for the shutdown signal. */ static gboolean _indicator_service_server_un_watch (IndicatorService * service, DBusGMethodInvocation * method) { diff --git a/libindicator/indicator-service.h b/libindicator/indicator-service.h index 59c5385..bda9cb7 100644 --- a/libindicator/indicator-service.h +++ b/libindicator/indicator-service.h @@ -1,3 +1,26 @@ +/* +An object used to provide a simple interface for a service +to query version and manage whether it's running. + +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/>. +*/ + #ifndef __INDICATOR_SERVICE_H__ #define __INDICATOR_SERVICE_H__ |