Back to index

bamf  0.2.120
bamf-indicator.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2010-2011 Canonical Ltd
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License version 3 as
00006  * published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Authored by: Jason Smith <jason.smith@canonical.com>
00017  *              Marco Trevisan (TreviƱo) <3v1n0@ubuntu.com>
00018  *
00019  */
00020 
00021 #include "bamf-indicator.h"
00022 
00023 #define BAMF_INDICATOR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), \
00024                                            BAMF_TYPE_INDICATOR, BamfIndicatorPrivate))
00025 
00026 enum
00027 {
00028   PROP_0,
00029   
00030   PROP_ADDRESS,
00031   PROP_PID,
00032   PROP_PATH,
00033   PROP_ID,
00034 };
00035 
00036 
00037 struct _BamfIndicatorPrivate
00038 {
00039   BamfDBusItemIndicator *dbus_iface;
00040   char *id;
00041   char *path;
00042   char *address;
00043   guint32 pid;
00044   GDBusProxy *proxy;
00045 };
00046 
00047 G_DEFINE_TYPE (BamfIndicator, bamf_indicator, BAMF_TYPE_VIEW)
00048 
00049 const char *
00050 bamf_indicator_get_path (BamfIndicator *self)
00051 {
00052   g_return_val_if_fail (BAMF_IS_INDICATOR (self), NULL);
00053   return self->priv->path;
00054 }
00055 
00056 const char *
00057 bamf_indicator_get_address (BamfIndicator *self)
00058 {
00059   g_return_val_if_fail (BAMF_IS_INDICATOR (self), NULL);
00060   return self->priv->address;
00061 }
00062 
00063 const char *
00064 bamf_indicator_get_id (BamfIndicator *self)
00065 {
00066   g_return_val_if_fail (BAMF_IS_INDICATOR (self), NULL);
00067   return self->priv->id;
00068 }
00069 
00070 guint32
00071 bamf_indicator_get_pid (BamfIndicator *self)
00072 {
00073   g_return_val_if_fail (BAMF_IS_INDICATOR (self), 0);
00074   return self->priv->pid;
00075 }
00076 
00077 gboolean
00078 bamf_indicator_matches_signature (BamfIndicator *self, gint pid, const char *address, const char *path)
00079 {
00080   g_return_val_if_fail (BAMF_IS_INDICATOR (self), FALSE);
00081 
00082   return g_strcmp0 (self->priv->address, address) == 0 &&
00083          g_strcmp0 (self->priv->path, path) == 0 &&
00084          pid == self->priv->pid;         
00085 }
00086 
00087 static const char *
00088 bamf_indicator_get_view_type (BamfView *view)
00089 {
00090   return "indicator";
00091 }
00092 
00093 static char *
00094 bamf_indicator_get_stable_bus_name (BamfView *view)
00095 {
00096   BamfIndicator *self;
00097 
00098   g_return_val_if_fail (BAMF_IS_INDICATOR (view), NULL);  
00099   self = BAMF_INDICATOR (view);
00100   
00101   return g_strdup_printf ("indicator%i", bamf_indicator_get_pid (self));
00102 }
00103 
00104 static void
00105 bamf_indicator_set_property (GObject *object, guint property_id,
00106                              const GValue *value, GParamSpec *pspec)
00107 {
00108   BamfIndicator *self;
00109 
00110   self = BAMF_INDICATOR (object);
00111 
00112   switch (property_id)
00113     {
00114       case PROP_ADDRESS:
00115         self->priv->address = g_value_dup_string (value);
00116         break;
00117       
00118       case PROP_PATH:
00119         self->priv->path = g_value_dup_string (value);
00120         break;
00121         
00122       case PROP_ID:
00123         self->priv->id = g_value_dup_string (value);
00124         break;
00125       
00126       case PROP_PID:
00127         self->priv->pid = g_value_get_uint (value);
00128         break;
00129 
00130       default:
00131         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
00132     }
00133 }
00134 
00135 static void
00136 bamf_indicator_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
00137 {
00138   BamfIndicator *self;
00139 
00140   self = BAMF_INDICATOR (object);
00141 
00142   switch (property_id)
00143     {
00144       case PROP_ADDRESS:
00145         g_value_set_string (value, self->priv->address);
00146         break;
00147       
00148       case PROP_PATH:
00149         g_value_set_string (value, self->priv->path);
00150         break;
00151       
00152       case PROP_ID:
00153         g_value_set_string (value, self->priv->id);
00154         break;
00155       
00156       case PROP_PID:
00157         g_value_set_uint (value, self->priv->pid);
00158         break;
00159 
00160       default:
00161         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
00162     }
00163 }
00164 
00165 static void
00166 bamf_indicator_on_destroy (GObject *object, GParamSpec *pspec, BamfIndicator *self)
00167 {
00168   g_object_unref (self->priv->proxy);
00169   self->priv->proxy = NULL;
00170 
00171   bamf_view_close (BAMF_VIEW (self));
00172 }
00173 
00174 static gboolean
00175 on_dbus_handle_path (BamfDBusItemIndicator *interface,
00176                      GDBusMethodInvocation *invocation,
00177                      BamfIndicator *self)
00178 {
00179   const char *path = bamf_indicator_get_path (self);
00180   g_dbus_method_invocation_return_value (invocation,
00181                                          g_variant_new ("(s)", path ? path : ""));
00182 
00183   return TRUE;
00184 }
00185 
00186 static gboolean
00187 on_dbus_handle_address (BamfDBusItemIndicator *interface,
00188                         GDBusMethodInvocation *invocation,
00189                         BamfIndicator *self)
00190 {
00191   const char *address = bamf_indicator_get_address (self);
00192   g_dbus_method_invocation_return_value (invocation,
00193                                          g_variant_new ("(s)", address ? address : ""));
00194 
00195   return TRUE;
00196 }
00197 
00198 static void
00199 bamf_indicator_constructed (GObject *object)
00200 {
00201   BamfIndicator *self;
00202   BamfIndicatorPrivate *priv;
00203   GDBusProxy *proxy;
00204   GError *error = NULL;
00205 
00206   if (G_OBJECT_CLASS (bamf_indicator_parent_class)->constructed)
00207     G_OBJECT_CLASS (bamf_indicator_parent_class)->constructed (object);
00208 
00209   self = BAMF_INDICATOR (object);
00210   priv = self->priv;
00211 
00212   proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
00213                                          G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES|
00214                                          G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS|
00215                                          G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
00216                                          NULL,
00217                                          priv->address,
00218                                          priv->path,
00219                                          "org.ayatana.indicator.application.service",
00220                                          NULL,
00221                                          &error);
00222 
00223   if (error)
00224     {
00225       g_debug ("Could not setup proxy: %s %s: %s", priv->address, priv->path,
00226                                                    error->message);
00227       g_error_free (error);
00228     }
00229   else
00230     {
00231       gchar *owner = g_dbus_proxy_get_name_owner (proxy);
00232 
00233       if (owner)
00234         {
00235           g_free (owner);
00236 
00237           g_signal_connect (G_OBJECT (proxy), "notify::g-name-owner",
00238                             G_CALLBACK (bamf_indicator_on_destroy), self);
00239 
00240           if (priv->proxy)
00241             g_object_unref (priv->proxy);
00242 
00243           priv->proxy = proxy;
00244         }
00245       else
00246         {
00247            g_debug ("Failed to get notification approver proxy: no owner available");
00248            g_object_unref (proxy);
00249         }
00250     }
00251 }
00252 
00253 static void
00254 bamf_indicator_dispose (GObject *object)
00255 {
00256   BamfIndicatorPrivate *priv;
00257   
00258   priv = BAMF_INDICATOR (object)->priv;
00259 
00260   if (priv->proxy)
00261     {
00262       g_object_unref (priv->proxy);
00263       priv->proxy = NULL;
00264     }
00265   
00266   if (priv->path)
00267     {
00268       g_free (priv->path);
00269       priv->path = NULL;
00270     }
00271 
00272   if (priv->address)
00273     {
00274       g_free (priv->address);
00275       priv->address = NULL;
00276     }
00277     
00278   if (priv->id)
00279     {
00280       g_free (priv->id);
00281       priv->id = NULL;
00282     }  
00283 
00284   G_OBJECT_CLASS (bamf_indicator_parent_class)->dispose (object);
00285 }
00286 
00287 static void
00288 bamf_indicator_finalize (GObject *object)
00289 {
00290   BamfIndicatorPrivate *priv;
00291   
00292   priv = BAMF_INDICATOR (object)->priv;
00293 
00294   g_object_unref (priv->dbus_iface);
00295 
00296   G_OBJECT_CLASS (bamf_indicator_parent_class)->finalize (object);
00297 }
00298 
00299 static void
00300 bamf_indicator_class_init (BamfIndicatorClass *klass)
00301 {
00302   GParamSpec *pspec;
00303   GObjectClass *object_class = G_OBJECT_CLASS (klass);
00304   BamfViewClass *view_class = BAMF_VIEW_CLASS (klass);
00305 
00306   object_class->constructed   = bamf_indicator_constructed;
00307   object_class->get_property  = bamf_indicator_get_property;
00308   object_class->set_property  = bamf_indicator_set_property;
00309   object_class->dispose       = bamf_indicator_dispose;
00310   object_class->finalize      = bamf_indicator_finalize;
00311 
00312   view_class->view_type       = bamf_indicator_get_view_type;
00313   view_class->stable_bus_name = bamf_indicator_get_stable_bus_name;
00314 
00315   pspec = g_param_spec_string ("address", "address", "address", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
00316   g_object_class_install_property (object_class, PROP_ADDRESS, pspec);
00317   
00318   pspec = g_param_spec_string ("path", "path", "path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
00319   g_object_class_install_property (object_class, PROP_PATH, pspec);
00320   
00321   pspec = g_param_spec_string ("id", "id", "id", NULL, G_PARAM_READWRITE);
00322   g_object_class_install_property (object_class, PROP_ID, pspec);
00323   
00324   pspec = g_param_spec_uint ("pid", "pid", "pid", 0, G_MAXUINT32, 0, G_PARAM_READWRITE);
00325   g_object_class_install_property (object_class, PROP_PID, pspec);
00326 
00327   g_type_class_add_private (object_class, sizeof (BamfIndicatorPrivate));
00328 }
00329 
00330 static void
00331 bamf_indicator_init (BamfIndicator *self)
00332 {
00333   self->priv = BAMF_INDICATOR_GET_PRIVATE (self);
00334 
00335   self->priv->dbus_iface = bamf_dbus_item_indicator_skeleton_new ();
00336 
00337   /* Registering signal callbacks to reply to dbus method calls */
00338   g_signal_connect (self->priv->dbus_iface, "handle-path",
00339                     G_CALLBACK (on_dbus_handle_path), self);
00340 
00341   g_signal_connect (self->priv->dbus_iface, "handle-address",
00342                     G_CALLBACK (on_dbus_handle_address), self);
00343 
00344   /* Setting the interface for the dbus object */
00345   bamf_dbus_item_object_skeleton_set_indicator (BAMF_DBUS_ITEM_OBJECT_SKELETON (self),
00346                                                 self->priv->dbus_iface);
00347 }
00348 
00349 BamfIndicator *
00350 bamf_indicator_new (const char *id, const char *path, const char *address, guint32 pid)
00351 {
00352   BamfIndicator *self;
00353   self = g_object_new (BAMF_TYPE_INDICATOR, 
00354                        "address", address,
00355                        "path", path,
00356                        "pid", pid,
00357                        "id", id,
00358                        NULL);
00359                        
00360   return self;
00361 }