Back to index

bamf  0.2.120
bamf-tab-source.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-view.h"
00022 #include "bamf-tab-source.h"
00023 #include "bamf-tab.h"
00024 #include "bamf-marshal.h"
00025 #include "bamf-gdbus-browser-generated.h"
00026 
00027 G_DEFINE_TYPE (BamfTabSource, bamf_tab_source, G_TYPE_OBJECT);
00028 #define BAMF_TAB_SOURCE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
00029 BAMF_TYPE_TAB_SOURCE, BamfTabSourcePrivate))
00030 
00031 enum
00032 {
00033   PROP_0,
00034 
00035   PROP_BUS,
00036   PROP_PATH,
00037 };
00038 
00039 enum
00040 {
00041   REMOTE_TAB_URI_CHANGED,
00042   REMOTE_TAB_OPENED,
00043   REMOTE_TAB_CLOSED,
00044   TAB_OPENED,
00045   TAB_CLOSED,
00046 
00047   LAST_SIGNAL,
00048 };
00049 
00050 static guint bamf_tab_source_signals[LAST_SIGNAL] = { 0 };
00051 
00052 struct _BamfTabSourcePrivate
00053 {
00054   BamfDBusBrowser *proxy;
00055   char       *bus;
00056   char       *path;
00057   GHashTable *tabs;
00058 };
00059 
00060 char **
00061 bamf_tab_source_tab_ids (BamfTabSource *self)
00062 {
00063   BamfTabSourcePrivate *priv;
00064   GError *error = NULL;
00065   char **ids = NULL;
00066 
00067   g_return_val_if_fail (BAMF_IS_TAB_SOURCE (self), NULL);
00068   priv = self->priv;
00069 
00070   if (!bamf_dbus_browser__call_tab_ids_sync (priv->proxy, &ids, NULL, &error))
00071     {
00072       g_warning ("Failed to get tab ids: %s", error->message);
00073       g_error_free (error);
00074       return NULL;
00075     }
00076 
00077   return ids;
00078 }
00079 
00080 void
00081 bamf_tab_source_show_tab (BamfTabSource *self, char *id)
00082 {
00083   BamfTabSourcePrivate *priv;
00084   GError *error = NULL;
00085 
00086   g_return_if_fail (BAMF_IS_TAB_SOURCE (self));
00087   priv = self->priv;
00088 
00089   if (!bamf_dbus_browser__call_show_tab_sync (priv->proxy, id, NULL, &error))
00090     {
00091       g_warning ("Failed to show tab: %s", error->message);
00092       g_error_free (error);
00093     }
00094 }
00095 
00096 gchar *
00097 bamf_tab_source_get_tab_preview (BamfTabSource *self,
00098                                  char *id)
00099 {
00100   BamfTabSourcePrivate *priv;
00101   GError *error = NULL;
00102   gchar *preview_data = NULL;
00103 
00104   g_return_val_if_fail (BAMF_IS_TAB_SOURCE (self), NULL);
00105   priv = self->priv;
00106 
00107   if (!bamf_dbus_browser__call_tab_preview_sync (priv->proxy, id, &preview_data,
00108                                                  NULL, &error))
00109     {
00110       g_warning ("Failed to get tab preview data: %s", error->message);
00111       g_error_free (error);
00112       return NULL;
00113     }
00114 
00115   return preview_data;
00116 }
00117 
00118 char *
00119 bamf_tab_source_get_tab_uri (BamfTabSource *self,
00120                              char *id)
00121 {
00122   BamfTabSourcePrivate *priv;
00123   GError *error = NULL;
00124   char *uri = NULL;
00125 
00126   g_return_val_if_fail (BAMF_IS_TAB_SOURCE (self), NULL);
00127   priv = self->priv;
00128 
00129   if (!bamf_dbus_browser__call_tab_uri_sync (priv->proxy, id, &uri, NULL, &error))
00130     {
00131       g_warning ("Failed to get tab URI: %s", error->message);
00132       g_error_free (error);
00133       return NULL;
00134     }
00135 
00136   return uri;
00137 }
00138 
00139 guint32
00140 bamf_tab_source_get_tab_xid (BamfTabSource *self,
00141                              char *id)
00142 {
00143   BamfTabSourcePrivate *priv;
00144   GError *error = NULL;
00145   guint32 xid = 0;
00146 
00147   g_return_val_if_fail (BAMF_IS_TAB_SOURCE (self), 0);
00148   priv = self->priv;
00149 
00150   if (!bamf_dbus_browser__call_tab_xid_sync (priv->proxy, id, &xid, NULL, &error))
00151     {
00152       g_warning ("Failed to get tab XID: %s", error->message);
00153       g_error_free (error);
00154       return 0;
00155     }
00156 
00157   return xid;
00158 }
00159 
00160 static void
00161 bamf_tab_source_on_tab_opened (BamfDBusBrowser *proxy, const char *id,
00162                                BamfTabSource *source)
00163 {
00164   BamfTab *tab;
00165 
00166   g_return_if_fail (BAMF_IS_TAB_SOURCE (source));
00167 
00168   g_signal_emit (source, REMOTE_TAB_OPENED, 0, id);
00169 
00170   tab = bamf_tab_new (source, id);
00171   g_hash_table_insert (source->priv->tabs, g_strdup (id), tab);
00172 
00173   g_signal_emit (source, TAB_OPENED, 0, tab);
00174 }
00175 
00176 static void
00177 bamf_tab_source_on_tab_closed (BamfDBusBrowser *proxy, const char *id,
00178                                BamfTabSource *source)
00179 {
00180   BamfTab *tab;
00181 
00182   g_return_if_fail (BAMF_IS_TAB_SOURCE (source));
00183 
00184   g_signal_emit (source, REMOTE_TAB_CLOSED, 0, id);
00185 
00186   tab = g_hash_table_lookup (source->priv->tabs, id);
00187 
00188   if (!BAMF_IS_TAB (tab))
00189     return;
00190 
00191   g_hash_table_remove (source->priv->tabs, id);
00192 
00193   g_signal_emit (source, TAB_CLOSED, 0, tab);
00194   g_object_unref (tab);
00195 }
00196 
00197 static void
00198 bamf_tab_source_on_uri_changed (BamfDBusBrowser *proxy, const char *id,
00199                                 const char *old_uri, char *new_uri, BamfTabSource *source)
00200 {
00201   g_signal_emit (source, REMOTE_TAB_URI_CHANGED, 0, id, old_uri, new_uri);
00202 }
00203 
00204 static void
00205 bamf_tab_source_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
00206 {
00207   BamfTabSource *self;
00208 
00209   self = BAMF_TAB_SOURCE (object);
00210 
00211   switch (property_id)
00212     {
00213       case PROP_PATH:
00214         self->priv->path = g_strdup (g_value_get_string (value));
00215         break;
00216       case PROP_BUS:
00217         self->priv->bus = g_strdup (g_value_get_string (value));
00218         break;
00219       default:
00220         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
00221     }
00222 }
00223 
00224 static void
00225 bamf_tab_source_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
00226 {
00227   BamfTabSource *self;
00228 
00229   self = BAMF_TAB_SOURCE (object);
00230 
00231   switch (property_id)
00232     {
00233       case PROP_PATH:
00234         g_value_set_string (value, self->priv->path);
00235         break;
00236       case PROP_BUS:
00237         g_value_set_string (value, self->priv->path);
00238         break;
00239       default:
00240         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
00241     }
00242 }
00243 
00244 static void bamf_tab_source_reconnect (GObject *object, GParamSpec *pspec, BamfTabSource *self);
00245 
00246 static void
00247 on_proxy_ready_cb (GDBusProxy *proxy, GAsyncResult *res, BamfTabSource *self)
00248 {
00249   BamfDBusBrowser *bproxy;
00250   GError *error = NULL;
00251   g_return_if_fail (BAMF_IS_TAB_SOURCE (self));
00252 
00253   bproxy = bamf_dbus_browser__proxy_new_for_bus_finish (res, &error);
00254 
00255   if (error)
00256     {
00257       g_critical ("Unable to get org.ayatana.bamf.browser object from bus %s: %s",
00258                   self->priv->bus, error->message);
00259       g_error_free (error);
00260     }
00261   else
00262     {
00263       gchar *owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (bproxy));
00264 
00265       if (owner)
00266         {
00267           g_free (owner);
00268 
00269           if (self->priv->proxy)
00270             g_object_unref (self->priv->proxy);
00271 
00272           self->priv->proxy = bproxy;
00273 
00274           g_signal_connect (self->priv->proxy, "tab-uri-changed",
00275                             (GCallback) bamf_tab_source_on_uri_changed, self);
00276 
00277           g_signal_connect (self->priv->proxy, "tab-opened",
00278                             (GCallback) bamf_tab_source_on_tab_opened, self);
00279 
00280           g_signal_connect (self->priv->proxy, "tab-closed",
00281                             (GCallback) bamf_tab_source_on_tab_closed, self);
00282 
00283           g_signal_connect (self->priv->proxy, "notify::g-name-owner",
00284                             G_CALLBACK (bamf_tab_source_reconnect), self);
00285 
00286         }
00287       else
00288         {
00289            g_debug ("Failed to get notification approver proxy: no owner available");
00290            g_object_unref (proxy);
00291         }
00292     }
00293 }
00294 
00295 static void
00296 bamf_tab_source_reconnect (GObject *object, GParamSpec *pspec, BamfTabSource *self)
00297 {
00298   g_return_if_fail (BAMF_IS_TAB_SOURCE (self));
00299 
00300   if (self->priv->proxy)
00301     {
00302       g_object_unref (self->priv->proxy);
00303       self->priv->proxy = NULL;
00304     }
00305 
00306   bamf_dbus_browser__proxy_new_for_bus (G_BUS_TYPE_SESSION,
00307                                         G_DBUS_PROXY_FLAGS_NONE,
00308                                         self->priv->bus,
00309                                         self->priv->path,
00310                                         NULL,
00311                                         (GAsyncReadyCallback) on_proxy_ready_cb,
00312                                         self);
00313 }
00314 
00315 static void
00316 bamf_tab_source_constructed (GObject *object)
00317 {
00318   BamfTabSource *source;
00319   BamfTabSourcePrivate *priv;
00320 
00321   if (G_OBJECT_CLASS (bamf_tab_source_parent_class)->constructed)
00322     G_OBJECT_CLASS (bamf_tab_source_parent_class)->constructed (object);
00323 
00324   source = BAMF_TAB_SOURCE (object);
00325   priv = source->priv;
00326 
00327   bamf_dbus_browser__proxy_new_for_bus (G_BUS_TYPE_SESSION,
00328                                         G_DBUS_PROXY_FLAGS_NONE,
00329                                         priv->bus,
00330                                         priv->path,
00331                                         NULL,
00332                                         (GAsyncReadyCallback) on_proxy_ready_cb,
00333                                         source);
00334 }
00335 
00336 static void
00337 bamf_tab_source_dispose (GObject *object)
00338 {
00339   BamfTabSource *self;
00340 
00341   self = BAMF_TAB_SOURCE (object);
00342 
00343   if (self->priv->bus)
00344     {
00345       g_free (self->priv->bus);
00346       self->priv->bus = NULL;
00347     }
00348 
00349   if (self->priv->path)
00350     {
00351       g_free (self->priv->path);
00352       self->priv->path = NULL;
00353     }
00354 
00355   if (self->priv->proxy)
00356     {
00357       g_object_unref (self->priv->proxy);
00358       self->priv->proxy = NULL;
00359     }
00360 
00361   G_OBJECT_CLASS (bamf_tab_source_parent_class)->dispose (object);
00362 }
00363 
00364 static void
00365 bamf_tab_source_init (BamfTabSource * self)
00366 {
00367   BamfTabSourcePrivate *priv;
00368   priv = self->priv = BAMF_TAB_SOURCE_GET_PRIVATE (self);
00369 
00370   priv->tabs = g_hash_table_new_full ((GHashFunc) g_str_hash,
00371                                       (GEqualFunc) g_str_equal,
00372                                       (GDestroyNotify) g_free,
00373                                       NULL);
00374 }
00375 
00376 static void
00377 bamf_tab_source_class_init (BamfTabSourceClass * klass)
00378 {
00379   GParamSpec *pspec;
00380   GObjectClass *object_class = G_OBJECT_CLASS (klass);
00381 
00382   object_class->dispose      = bamf_tab_source_dispose;
00383   object_class->set_property = bamf_tab_source_set_property;
00384   object_class->get_property = bamf_tab_source_get_property;
00385   object_class->constructed  = bamf_tab_source_constructed;
00386 
00387   g_type_class_add_private (klass, sizeof (BamfTabSourcePrivate));
00388 
00389   pspec = g_param_spec_string ("path", "path", "path", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
00390   g_object_class_install_property (object_class, PROP_PATH, pspec);
00391 
00392   pspec = g_param_spec_string ("bus", "bus", "bus", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
00393   g_object_class_install_property (object_class, PROP_BUS, pspec);
00394 
00395   bamf_tab_source_signals [REMOTE_TAB_URI_CHANGED] =
00396     g_signal_new ("remote-tab-uri-changed",
00397                   G_OBJECT_CLASS_TYPE (klass),
00398                   G_SIGNAL_RUN_FIRST,
00399                   0,
00400                   NULL, NULL,
00401                   bamf_marshal_VOID__STRING_STRING_STRING,
00402                   G_TYPE_NONE, 3,
00403                   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
00404 
00405   bamf_tab_source_signals [REMOTE_TAB_OPENED] =
00406     g_signal_new ("remote-tab-opened",
00407                   G_OBJECT_CLASS_TYPE (klass),
00408                   G_SIGNAL_RUN_FIRST,
00409                   0,
00410                   NULL, NULL,
00411                   g_cclosure_marshal_VOID__STRING,
00412                   G_TYPE_NONE, 1,
00413                   G_TYPE_STRING);
00414 
00415   bamf_tab_source_signals [REMOTE_TAB_CLOSED] =
00416     g_signal_new ("remote-tab-closed",
00417                   G_OBJECT_CLASS_TYPE (klass),
00418                   G_SIGNAL_RUN_FIRST,
00419                   0,
00420                   NULL, NULL,
00421                   g_cclosure_marshal_VOID__STRING,
00422                   G_TYPE_NONE, 1,
00423                   G_TYPE_STRING);
00424 
00425   bamf_tab_source_signals [TAB_OPENED] =
00426     g_signal_new ("tab-opened",
00427                   G_OBJECT_CLASS_TYPE (klass),
00428                   G_SIGNAL_RUN_FIRST,
00429                   0,
00430                   NULL, NULL,
00431                   g_cclosure_marshal_VOID__OBJECT,
00432                   G_TYPE_NONE, 1,
00433                   BAMF_TYPE_TAB);
00434 
00435   bamf_tab_source_signals [TAB_CLOSED] =
00436     g_signal_new ("tab-closed",
00437                   G_OBJECT_CLASS_TYPE (klass),
00438                   G_SIGNAL_RUN_FIRST,
00439                   0,
00440                   NULL, NULL,
00441                   g_cclosure_marshal_VOID__OBJECT,
00442                   G_TYPE_NONE, 1,
00443                   BAMF_TYPE_TAB);
00444 }
00445 
00446 BamfTabSource *
00447 bamf_tab_source_new (char *bus, char *path)
00448 {
00449   BamfTabSource *self;
00450   self = (BamfTabSource *) g_object_new (BAMF_TYPE_TAB_SOURCE,
00451                                          "path", path,
00452                                          "bus", bus,
00453                                          NULL);
00454 
00455   return self;
00456 }