Back to index

libindicator  12.10.0
Classes
indicator-service-manager.c File Reference
#include <stdlib.h>
#include <gio/gio.h>
#include "indicator-service-manager.h"
#include "gen-indicator-service.xml.h"
#include "dbus-shared.h"

Go to the source code of this file.

Classes

struct  _IndicatorServiceManagerPrivate

: The well known dbus name the service should be on.

IndicatorServiceManagerPrivate:

: The proxy to the service itself.

: Whether we're connected to the service or not. : The version of the service that we're looking for. : The number of times we've restarted this service.

#define TIMEOUT_ENV_NAME   "INDICATOR_SERVICE_RESTART_DISABLE"
#define TIMEOUT_MULTIPLIER   100 /* In ms */
#define TIMEOUT_A_LITTLE_WHILE   5
#define PROP_NAME_S   "name"
#define PROP_VERSION_S   "version"
#define INDICATOR_SERVICE_MANAGER_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerPrivate))
enum  { CONNECTION_CHANGE, LAST_SIGNAL }
enum  { PROP_0, PROP_NAME, PROP_VERSION }
typedef struct _IndicatorServiceManagerPrivate
static guint signals [LAST_SIGNAL] = { 0 }
static GDBusNodeInfo * node_info = NULL
static GDBusInterfaceInfo * interface_info = NULL
static void indicator_service_manager_class_init (IndicatorServiceManagerClass *klass)
static void indicator_service_manager_init (IndicatorServiceManager *self)
static void indicator_service_manager_dispose (GObject *object)
static void indicator_service_manager_finalize (GObject *object)
static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static void start_service (IndicatorServiceManager *service)
static void start_service_again (IndicatorServiceManager *manager)
static void unwatch (GDBusProxy *proxy)
static void service_proxy_cb (GObject *object, GAsyncResult *res, gpointer user_data)
static void service_proxy_name_changed (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data)
 G_DEFINE_TYPE (IndicatorServiceManager, indicator_service_manager, G_TYPE_OBJECT)
static void watch_cb (GObject *object, GAsyncResult *res, gpointer user_data)
static gboolean start_service_again_cb (gpointer data)
IndicatorServiceManager * indicator_service_manager_new (const gchar *dbus_name)
 indicator_service_manager_new: : The well known name of the service on DBus
IndicatorServiceManager * indicator_service_manager_new_version (const gchar *dbus_name, guint version)
 inicator_service_manager_new_version: : The well known name of the service on DBus
gboolean indicator_service_manager_connected (IndicatorServiceManager *sm)
 indicator_service_manager_connected: : #IndicatorServiceManager object to check
void indicator_service_manager_set_refresh (IndicatorServiceManager *sm, guint time_in_ms)
 indicator_service_manager_set_refresh: : #IndicatorServiceManager object to configure : The refresh time in milliseconds

Class Documentation

struct _IndicatorServiceManagerPrivate

Definition at line 45 of file indicator-service-manager.c.

Class Members
gboolean connected
gchar * name
guint name_watcher
guint restart_count
gint restart_source
GDBusProxy * service_proxy
GCancellable * service_proxy_cancel
guint this_service_version
GCancellable * watch_cancel

Define Documentation

#define INDICATOR_SERVICE_MANAGER_GET_PRIVATE (   o)    (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerPrivate))

Definition at line 91 of file indicator-service-manager.c.

#define PROP_NAME_S   "name"

Definition at line 83 of file indicator-service-manager.c.

#define PROP_VERSION_S   "version"

Definition at line 84 of file indicator-service-manager.c.

#define TIMEOUT_A_LITTLE_WHILE   5

Definition at line 71 of file indicator-service-manager.c.

#define TIMEOUT_ENV_NAME   "INDICATOR_SERVICE_RESTART_DISABLE"

Definition at line 66 of file indicator-service-manager.c.

#define TIMEOUT_MULTIPLIER   100 /* In ms */

Definition at line 67 of file indicator-service-manager.c.


Typedef Documentation

Definition at line 44 of file indicator-service-manager.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
CONNECTION_CHANGE 
LAST_SIGNAL 

Definition at line 58 of file indicator-service-manager.c.

anonymous enum
Enumerator:
PROP_0 
PROP_NAME 
PROP_VERSION 

Definition at line 76 of file indicator-service-manager.c.


Function Documentation

G_DEFINE_TYPE ( IndicatorServiceManager  ,
indicator_service_manager  ,
G_TYPE_OBJECT   
)
static void get_property ( GObject *  object,
guint  prop_id,
GValue *  value,
GParamSpec *  pspec 
) [static]

Definition at line 314 of file indicator-service-manager.c.

{
       IndicatorServiceManager * self = INDICATOR_SERVICE_MANAGER(object);
       g_return_if_fail(self != NULL);

       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self);
       g_return_if_fail(priv != NULL);

       switch (prop_id) {
       /* *********************** */
       case PROP_NAME:
              g_value_set_string(value, priv->name);
              break;
       /* *********************** */
       case PROP_VERSION:
              g_value_set_uint(value, priv->this_service_version);
              break;
       /* *********************** */
       default:
              G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
              break;
       }

       return;
}

Here is the caller graph for this function:

static void indicator_service_manager_class_init ( IndicatorServiceManagerClass *  klass) [static]

IndicatorServiceManager::connecton-change: : The #IndicatorServiceManager object : The state of the connection, TRUE is connected.

Signaled when the service is connected or disconnected depending on it's previous state.

Definition at line 113 of file indicator-service-manager.c.

{
       GObjectClass *object_class = G_OBJECT_CLASS (klass);

       g_type_class_add_private (klass, sizeof (IndicatorServiceManagerPrivate));

       object_class->dispose = indicator_service_manager_dispose;
       object_class->finalize = indicator_service_manager_finalize;

       /* Property funcs */
       object_class->set_property = set_property;
       object_class->get_property = get_property;

       signals[CONNECTION_CHANGE] = g_signal_new (INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE,
                                         G_TYPE_FROM_CLASS(klass),
                                         G_SIGNAL_RUN_LAST,
                                         G_STRUCT_OFFSET (IndicatorServiceManagerClass, connection_change),
                                         NULL, NULL,
                                         g_cclosure_marshal_VOID__BOOLEAN,
                                         G_TYPE_NONE, 1, G_TYPE_BOOLEAN, G_TYPE_NONE);

       /* Properties */
       g_object_class_install_property(object_class, PROP_NAME,
                                       g_param_spec_string(PROP_NAME_S,
                                                           "The DBus name for the service to monitor",
                                                           "This is the name that should be used to start a service.",
                                                           NULL,
                                                           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       g_object_class_install_property(object_class, PROP_VERSION,
                                       g_param_spec_uint(PROP_VERSION_S,
                                                         "The version of the service that we're expecting.",
                                                         "A number to check and reject a service if it gives us the wrong number.  This should match across the manager and the service",
                                                         0, G_MAXUINT, 0,
                                                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

       /* Setting up the DBus interfaces */
       if (node_info == NULL) {
              GError * error = NULL;

              node_info = g_dbus_node_info_new_for_xml(_indicator_service, &error);
              if (error != NULL) {
                     g_error("Unable to parse Indicator Service Interface description: %s", error->message);
                     g_error_free(error);
              }
       }

       if (interface_info == NULL) {
              interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_SERVICE_INTERFACE);

              if (interface_info == NULL) {
                     g_error("Unable to find interface '" INDICATOR_SERVICE_INTERFACE "'");
              }
       }

       return;
}

Here is the call graph for this function:

gboolean indicator_service_manager_connected ( IndicatorServiceManager *  sm)

indicator_service_manager_connected: : #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.

Definition at line 683 of file indicator-service-manager.c.

{
       g_return_val_if_fail(INDICATOR_IS_SERVICE_MANAGER(sm), FALSE);
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(sm);
       return priv->connected;
}
static void indicator_service_manager_dispose ( GObject *  object) [static]

Definition at line 205 of file indicator-service-manager.c.

{
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object);

       /* Removing the idle task to restart if it exists. */
       if (priv->restart_source != 0) {
              g_source_remove(priv->restart_source);
       }
       /* Block any restart calls */
       priv->restart_source = -1;

       /* If we were connected we need to make sure to
          tell people that it's no longer the case. */
       if (priv->connected) {
              priv->connected = FALSE;
              g_signal_emit(object, signals[CONNECTION_CHANGE], 0, FALSE, TRUE);
       }

       if (priv->name_watcher != 0) {
              g_dbus_connection_signal_unsubscribe(g_dbus_proxy_get_connection(priv->service_proxy),
                                                   priv->name_watcher);
              priv->name_watcher = 0;
       }

       /* If we're still getting the proxy, stop looking so we
          can then clean up some more. */
       if (priv->service_proxy_cancel != NULL) {
              g_cancellable_cancel(priv->service_proxy_cancel);
              g_object_unref(priv->service_proxy_cancel);
              priv->service_proxy_cancel = NULL;
       }

       /* If we've sent a watch, cancel looking for the reply before
          sending the unwatch */
       if (priv->watch_cancel != NULL) {
              g_cancellable_cancel(priv->watch_cancel);
              g_object_unref(priv->watch_cancel);
              priv->watch_cancel = NULL;
       }

       /* If we have a proxy, tell it we're shutting down.  Just
          to be polite about it. */
       if (priv->service_proxy != NULL) {
              unwatch(priv->service_proxy);
       }

       /* Destory our service proxy, we won't need it. */
       if (priv->service_proxy != NULL) {
              g_object_unref(G_OBJECT(priv->service_proxy));
              priv->service_proxy = NULL;
       }

       /* Let's see if our parents want to do anything. */
       G_OBJECT_CLASS (indicator_service_manager_parent_class)->dispose (object);
       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void indicator_service_manager_finalize ( GObject *  object) [static]

Definition at line 264 of file indicator-service-manager.c.

{
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object);

       if (priv->name != NULL) {
              g_free(priv->name);
              priv->name = NULL;
       }

       G_OBJECT_CLASS (indicator_service_manager_parent_class)->finalize (object);
       return;
}

Here is the caller graph for this function:

static void indicator_service_manager_init ( IndicatorServiceManager *  self) [static]

Definition at line 182 of file indicator-service-manager.c.

{
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self);

       /* Get the private variables in a decent state */
       priv->name = NULL;
       priv->service_proxy = NULL;
       priv->service_proxy_cancel = NULL;
       priv->name_watcher = 0;
       priv->connected = FALSE;
       priv->this_service_version = 0;
       priv->restart_count = 0;
       priv->restart_source = 0;
       priv->watch_cancel = NULL;

       return;
}
IndicatorServiceManager* indicator_service_manager_new ( const gchar *  dbus_name)

indicator_service_manager_new: : 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.

Definition at line 639 of file indicator-service-manager.c.

{
       GObject * obj = g_object_new(INDICATOR_SERVICE_MANAGER_TYPE,
                                    PROP_NAME_S, dbus_name,
                                    NULL);

       return INDICATOR_SERVICE_MANAGER(obj);
}

Here is the caller graph for this function:

IndicatorServiceManager* indicator_service_manager_new_version ( const gchar *  dbus_name,
guint  version 
)

inicator_service_manager_new_version: : 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.

Definition at line 663 of file indicator-service-manager.c.

{
       GObject * obj = g_object_new(INDICATOR_SERVICE_MANAGER_TYPE,
                                    PROP_NAME_S, dbus_name,
                                    PROP_VERSION_S, version,
                                    NULL);

       return INDICATOR_SERVICE_MANAGER(obj);
}

Here is the caller graph for this function:

void indicator_service_manager_set_refresh ( IndicatorServiceManager *  sm,
guint  time_in_ms 
)

indicator_service_manager_set_refresh: : #IndicatorServiceManager object to configure : 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.

Definition at line 702 of file indicator-service-manager.c.

{

       return;
}
static void service_proxy_cb ( GObject *  object,
GAsyncResult *  res,
gpointer  user_data 
) [static]

Definition at line 457 of file indicator-service-manager.c.

{
       GError * error = NULL;

       IndicatorServiceManager * service = INDICATOR_SERVICE_MANAGER(user_data);
       g_return_if_fail(service != NULL);

       GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);

       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data);

       if (priv->service_proxy_cancel != NULL) {
              g_object_unref(priv->service_proxy_cancel);
              priv->service_proxy_cancel = NULL;
       }

       if (error != NULL) {
              /* Unable to create the proxy, eh, let's try again
                 in a bit */
              g_error_free(error);
              start_service_again(service);
              return;
       }

       gchar * name = g_dbus_proxy_get_name_owner(proxy);
       if (name == NULL) {
              /* Hmm, since creating the proxy should start it, it seems very
                 odd that it wouldn't have an owner at this point.  But, all
                 we can do is try again. */
              g_object_unref(proxy);
              start_service_again(service);
              return;
       }
       g_free(name);

       /* Okay, we're good to grab the proxy at this point, we're
          sure that it's ours. */
       priv->service_proxy = proxy;

       /* Signal for drop */
       priv->name_watcher = g_dbus_connection_signal_subscribe(
                                          g_dbus_proxy_get_connection(proxy),
                                          "org.freedesktop.DBus",
                                          "org.freedesktop.DBus",
                                          "NameOwnerChanged",
                                          "/org/freedesktop/DBus",
                                          g_dbus_proxy_get_name(proxy),
                                          G_DBUS_SIGNAL_FLAGS_NONE,
                                          service_proxy_name_changed,
                                          user_data,
                                          NULL);

       /* Build cancelable if we need it */
       if (priv->watch_cancel == NULL) {
              priv->watch_cancel = g_cancellable_new();
       }

       /* Send watch */
       g_dbus_proxy_call(priv->service_proxy,
                         "Watch",
                         NULL, /* params */
                         G_DBUS_CALL_FLAGS_NONE,
                         -1,
                         priv->watch_cancel,
                         watch_cb,
                         user_data);

       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void service_proxy_name_changed ( GDBusConnection *  connection,
const gchar *  sender_name,
const gchar *  object_path,
const gchar *  interface_name,
const gchar *  signal_name,
GVariant *  parameters,
gpointer  user_data 
) [static]

Definition at line 531 of file indicator-service-manager.c.

{
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data);

       const gchar * new_name = NULL;
       const gchar * prev_name = NULL;
       g_variant_get(parameters, "(&s&s&s)", NULL, &prev_name, &new_name);

       if (new_name == NULL || new_name[0] == 0) {
              if (priv->connected) {
                     priv->connected = FALSE;
                     g_signal_emit(G_OBJECT(user_data), signals[CONNECTION_CHANGE], 0, FALSE, TRUE);
              }

              start_service_again(INDICATOR_SERVICE_MANAGER(user_data));
       } else {
              /* If we weren't connected before, we are now.  Let's tell the
                 world! */
              if (!priv->connected) {
                     priv->connected = TRUE;
                     g_signal_emit(G_OBJECT(user_data), signals[CONNECTION_CHANGE], 0, TRUE, TRUE);
              }

              /* If the names are both valid, and they're not the same, it means that
                 we've actually changed.  So we need to tell the new guy that we're
                 watching them */
              if (new_name != NULL && prev_name != NULL && new_name[0] != 0 && prev_name != 0 && g_strcmp0(prev_name, new_name) != 0) {
                     /* Send watch */
                     g_dbus_proxy_call(priv->service_proxy,
                                       "Watch",
                                       NULL, /* params */
                                       G_DBUS_CALL_FLAGS_NONE,
                                       -1,
                                       priv->watch_cancel,
                                       watch_cb,
                                       user_data);
              }
       }

       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void set_property ( GObject *  object,
guint  prop_id,
const GValue *  value,
GParamSpec *  pspec 
) [static]

Definition at line 280 of file indicator-service-manager.c.

{
       IndicatorServiceManager * self = INDICATOR_SERVICE_MANAGER(object);
       g_return_if_fail(self != NULL);

       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self);
       g_return_if_fail(priv != NULL);

       switch (prop_id) {
       /* *********************** */
       case PROP_NAME:
              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:
              priv->this_service_version = g_value_get_uint(value);
              break;
       /* *********************** */
       default:
              G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
              break;
       }

       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void start_service ( IndicatorServiceManager *  service) [static]

Definition at line 422 of file indicator-service-manager.c.

{
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(service);

       g_return_if_fail(priv->name != NULL);

       if (priv->service_proxy_cancel != NULL) {
              /* A service proxy is being gotten currently */
              return;
       }

       if (priv->service_proxy != NULL) {
              g_object_unref(priv->service_proxy);
              priv->service_proxy = NULL;
       }

       priv->service_proxy_cancel = g_cancellable_new();

       g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
                                G_DBUS_PROXY_FLAGS_NONE,
                                interface_info,
                                priv->name,
                                INDICATOR_SERVICE_OBJECT,
                                INDICATOR_SERVICE_INTERFACE,
                                priv->service_proxy_cancel,
                                service_proxy_cb,
                                service);

       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void start_service_again ( IndicatorServiceManager *  manager) [static]

Definition at line 596 of file indicator-service-manager.c.

{
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(manager);

       /* If we've already got a restart source running then
          let's not do this again. */
       if (priv->restart_source != 0) {
              return;
       }

       /* Allow the restarting to be disabled */
       if (g_getenv(TIMEOUT_ENV_NAME)) {
              return;
       }

       if (priv->restart_count == 0) {
              /* First time, do it in idle */
              g_idle_add(start_service_again_cb, manager);
       } else {
              /* Not our first time 'round the block.  Let's slow this down. */
              if (priv->restart_count > 16)
                     priv->restart_count = 16; /* Not more than 1024x */
              priv->restart_source = g_timeout_add((1 << priv->restart_count) * TIMEOUT_MULTIPLIER, start_service_again_cb, manager);
       }

       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean start_service_again_cb ( gpointer  data) [static]

Definition at line 581 of file indicator-service-manager.c.

{
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(data);
       priv->restart_count++;
       g_debug("Restarting service '%s' count %d", priv->name, priv->restart_count);
       start_service(INDICATOR_SERVICE_MANAGER(data));
       priv->restart_source = 0;
       return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void unwatch ( GDBusProxy *  proxy) [static]

Definition at line 343 of file indicator-service-manager.c.

{
       g_dbus_proxy_call(proxy,
                         "UnWatch",
                         NULL,   /* parameters */
                         G_DBUS_CALL_FLAGS_NONE,
                         -1,     /* timeout */
                         NULL,   /* cancelable */
                         NULL,   /* callback */
                         NULL);  /* user data */
       return;
}

Here is the caller graph for this function:

static void watch_cb ( GObject *  object,
GAsyncResult *  res,
gpointer  user_data 
) [static]

Definition at line 363 of file indicator-service-manager.c.

{
       GError * error = NULL;
       IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data);

       GVariant * params = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error);

       if (error != NULL) {
              g_warning("Unable to set watch on '%s': '%s'", priv->name, error->message);
              g_error_free(error);
              start_service_again(INDICATOR_SERVICE_MANAGER(user_data));
              return;
       }

       guint service_api_version;
       guint this_service_version;

       g_variant_get(params, "(uu)", &service_api_version, &this_service_version);
       g_variant_unref(params);

       /* We've done it, now let's stop counting. */
       /* Note: we're not checking versions.  Because, the hope is that
          the guy holding the name we want with the wrong version will
          drop and we can start another service quickly. */
       priv->restart_count = 0;

       if (service_api_version != INDICATOR_SERVICE_VERSION) {
              g_warning("Service is using a different version of the service interface.  Expecting %d and got %d.", INDICATOR_SERVICE_VERSION, service_api_version);
              unwatch(priv->service_proxy);

              /* Let's make us wait a little while, then try again */
              priv->restart_count = TIMEOUT_A_LITTLE_WHILE;
              start_service_again(INDICATOR_SERVICE_MANAGER(user_data));
              return;
       }

       if (this_service_version != priv->this_service_version) {
              g_warning("Service is using a different API version than the manager.  Expecting %d and got %d.", priv->this_service_version, this_service_version);
              unwatch(priv->service_proxy);

              /* Let's make us wait a little while, then try again */
              priv->restart_count = TIMEOUT_A_LITTLE_WHILE;
              start_service_again(INDICATOR_SERVICE_MANAGER(user_data));
              return;
       }

       if (!priv->connected) {
              priv->connected = TRUE;
              g_signal_emit(G_OBJECT(user_data), signals[CONNECTION_CHANGE], 0, TRUE, TRUE);
       }

       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

GDBusInterfaceInfo* interface_info = NULL [static]

Definition at line 88 of file indicator-service-manager.c.

GDBusNodeInfo* node_info = NULL [static]

Definition at line 87 of file indicator-service-manager.c.

guint signals[LAST_SIGNAL] = { 0 } [static]

Definition at line 63 of file indicator-service-manager.c.