Back to index

bamf  0.2.120
bamf-indicator.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Canonical Ltd.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of either or both of the following licenses:
00006  *
00007  * 1) the GNU Lesser General Public License version 3, as published by the
00008  * Free Software Foundation; and/or
00009  * 2) the GNU Lesser General Public License version 2.1, as published by
00010  * the Free Software Foundation.
00011  *
00012  * This program is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranties of
00014  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00015  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00016  * License for more details.
00017  *
00018  * You should have received a copy of both the GNU Lesser General Public
00019  * License version 3 and version 2.1 along with this program.  If not, see
00020  * <http://www.gnu.org/licenses/>
00021  *
00022  * Authored by: Jason Smith <jason.smith@canonical.com>
00023  *              Neil Jagdish Patel <neil.patel@canonical.com>
00024  *
00025  */
00033 #if HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036 
00037 #include "bamf-view-private.h"
00038 #include "bamf-indicator.h"
00039 #include "bamf-factory.h"
00040 #include <dbus/dbus.h>
00041 #include <dbus/dbus-glib.h>
00042 #include <dbus/dbus-glib-lowlevel.h>
00043 
00044 G_DEFINE_TYPE (BamfIndicator, bamf_indicator, BAMF_TYPE_VIEW);
00045 
00046 #define BAMF_INDICATOR_GET_PRIVATE(o) \
00047   (G_TYPE_INSTANCE_GET_PRIVATE ((o), BAMF_TYPE_INDICATOR, BamfIndicatorPrivate))
00048 
00049 struct _BamfIndicatorPrivate
00050 {
00051   DBusGConnection *connection;
00052   DBusGProxy      *proxy;
00053   gchar *path;
00054   gchar *dbus_menu;
00055   gchar *address;
00056 };
00057 
00058 const gchar * 
00059 bamf_indicator_get_dbus_menu_path (BamfIndicator *self)
00060 {
00061   BamfIndicatorPrivate *priv;
00062   gchar *path = NULL;
00063   DBusGProxy *proxy;
00064   GValue value = {0};
00065   GError *error = NULL;
00066 
00067   g_return_val_if_fail (BAMF_IS_INDICATOR (self), NULL);
00068   priv = self->priv;
00069   
00070   if (priv->dbus_menu)
00071     return priv->dbus_menu;
00072   
00073   if (!_bamf_view_remote_ready (BAMF_VIEW (self)))
00074     return NULL;
00075   
00076   proxy = dbus_g_proxy_new_for_name (priv->connection,
00077                                      bamf_indicator_get_remote_address (self),
00078                                      bamf_indicator_get_remote_path (self),
00079                                      "org.freedesktop.DBus.Properties");
00080   
00081   if (!dbus_g_proxy_call (proxy,
00082                           "Get",
00083                           &error,
00084                           G_TYPE_STRING, "org.kde.StatusNotifierItem",
00085                           G_TYPE_STRING, "Menu",
00086                           G_TYPE_INVALID,
00087                           G_TYPE_VALUE, &value,
00088                           G_TYPE_INVALID))
00089     {
00090       g_warning ("Failed to fetch remote path: %s", error->message);
00091       g_error_free (error);
00092       
00093       return NULL;
00094     }
00095   
00096   path = g_value_get_boxed (&value);
00097   priv->dbus_menu = path;
00098 
00099   g_object_unref (proxy);
00100   return priv->dbus_menu;
00101 }
00102 
00103 const gchar * 
00104 bamf_indicator_get_remote_path (BamfIndicator *self)
00105 {
00106   BamfIndicatorPrivate *priv;
00107   char *path = NULL;
00108   GError *error = NULL;
00109 
00110   g_return_val_if_fail (BAMF_IS_INDICATOR (self), NULL);
00111   priv = self->priv;
00112   
00113   if (priv->path)
00114     return priv->path;
00115   
00116   if (!_bamf_view_remote_ready (BAMF_VIEW (self)))
00117     return NULL;
00118   
00119   if (!dbus_g_proxy_call (priv->proxy,
00120                           "Path",
00121                           &error,
00122                           G_TYPE_INVALID,
00123                           G_TYPE_STRING, &path,
00124                           G_TYPE_INVALID))
00125     {
00126       g_warning ("Failed to fetch remote path: %s", error->message);
00127       g_error_free (error);
00128       
00129       return NULL;
00130     }
00131 
00132   priv->path = path;
00133 
00134   return path;
00135 }
00136 
00137 const gchar * 
00138 bamf_indicator_get_remote_address (BamfIndicator *self)
00139 {
00140   BamfIndicatorPrivate *priv;
00141   char *address = NULL;
00142   GError *error = NULL;
00143 
00144   g_return_val_if_fail (BAMF_IS_INDICATOR (self), NULL);
00145   priv = self->priv;
00146   
00147   if (priv->address)
00148     return priv->address;
00149   
00150   if (!_bamf_view_remote_ready (BAMF_VIEW (self)))
00151     return NULL;
00152   
00153   if (!dbus_g_proxy_call (priv->proxy,
00154                           "Address",
00155                           &error,
00156                           G_TYPE_INVALID,
00157                           G_TYPE_STRING, &address,
00158                           G_TYPE_INVALID))
00159     {
00160       g_warning ("Failed to fetch remote path: %s", error->message);
00161       g_error_free (error);
00162       
00163       return NULL;
00164     }
00165 
00166   priv->address = address;
00167 
00168   return address;
00169 }
00170 
00171 static void
00172 bamf_indicator_dispose (GObject *object)
00173 {
00174   BamfIndicator *self;
00175   BamfIndicatorPrivate *priv;
00176   
00177   self = BAMF_INDICATOR (object);
00178   priv = self->priv;
00179 
00180   if (priv->proxy)
00181     {
00182       g_object_unref (priv->proxy);
00183       priv->proxy = NULL;
00184     }
00185   
00186   if (priv->path)
00187     {
00188       g_free (priv->path);
00189       priv->path = NULL;
00190     }
00191   
00192   if (priv->dbus_menu)
00193     {
00194       g_free (priv->dbus_menu);
00195       priv->dbus_menu = NULL;
00196     }
00197   
00198   if (priv->address)
00199     {
00200       g_free (priv->address);
00201       priv->address = NULL;
00202     }
00203   
00204   if (G_OBJECT_CLASS (bamf_indicator_parent_class)->dispose)
00205     G_OBJECT_CLASS (bamf_indicator_parent_class)->dispose (object);
00206 }
00207 
00208 static void
00209 bamf_indicator_set_path (BamfView *view, const char *path)
00210 {
00211   BamfIndicator *self;
00212   BamfIndicatorPrivate *priv;
00213   
00214   self = BAMF_INDICATOR (view);
00215   priv = self->priv;
00216 
00217   if (priv->proxy)
00218     {
00219       g_object_unref (priv->proxy);
00220     }
00221 
00222   priv->proxy = dbus_g_proxy_new_for_name (priv->connection,
00223                                            "org.ayatana.bamf",
00224                                            path,
00225                                            "org.ayatana.bamf.indicator");
00226   if (priv->proxy == NULL)
00227     {
00228       g_error ("Unable to get org.ayatana.bamf.indicator indicator");
00229     }
00230 }
00231 
00232 static void
00233 bamf_indicator_class_init (BamfIndicatorClass *klass)
00234 {
00235   GObjectClass  *obj_class  = G_OBJECT_CLASS (klass);
00236   BamfViewClass *view_class = BAMF_VIEW_CLASS (klass);
00237 
00238   g_type_class_add_private (obj_class, sizeof (BamfIndicatorPrivate));
00239   
00240   obj_class->dispose     = bamf_indicator_dispose;
00241   view_class->set_path   = bamf_indicator_set_path;
00242 }
00243 
00244 
00245 static void
00246 bamf_indicator_init (BamfIndicator *self)
00247 {
00248   BamfIndicatorPrivate *priv;
00249   GError           *error = NULL;
00250 
00251   priv = self->priv = BAMF_INDICATOR_GET_PRIVATE (self);
00252 
00253   priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
00254   if (priv->connection == NULL)
00255     {
00256       g_critical ("Failed to open connection to bus: %s",
00257                error != NULL ? error->message : "Unknown");
00258       if (error)
00259         g_error_free (error);
00260       return;
00261     }
00262 }
00263 
00264 BamfIndicator *
00265 bamf_indicator_new (const char * path)
00266 {
00267   BamfIndicator *self;
00268   self = g_object_new (BAMF_TYPE_INDICATOR, NULL);
00269 
00270   _bamf_view_set_path (BAMF_VIEW (self), path);
00271 
00272   return self;
00273 }