aboutsummaryrefslogtreecommitdiff
path: root/libindicator
diff options
context:
space:
mode:
Diffstat (limited to 'libindicator')
-rw-r--r--libindicator/indicator-service-manager.c134
-rw-r--r--libindicator/indicator-service-manager.h23
-rw-r--r--libindicator/indicator-service.c62
-rw-r--r--libindicator/indicator-service.h23
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__