Back to index

bamf  0.2.120
bamf-view.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 
00023 #define BAMF_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
00024                                     BAMF_TYPE_VIEW, BamfViewPrivate))
00025 
00026 static void bamf_view_dbus_view_iface_init (BamfDBusItemViewIface *iface);
00027 G_DEFINE_TYPE_WITH_CODE (BamfView, bamf_view, BAMF_DBUS_ITEM_TYPE_OBJECT_SKELETON,
00028                          G_IMPLEMENT_INTERFACE (BAMF_DBUS_ITEM_TYPE_VIEW,
00029                                                 bamf_view_dbus_view_iface_init));
00030 
00031 enum
00032 {
00033   PROP_0,
00034 
00035   PROP_ACTIVE,
00036   PROP_RUNNING,
00037   PROP_URGENT,
00038   PROP_USER_VISIBLE,
00039 };
00040 
00041 enum
00042 {
00043   CLOSED_INTERNAL,
00044   EXPORTED,
00045 
00046   LAST_SIGNAL,
00047 };
00048 
00049 static guint view_signals[LAST_SIGNAL] = { 0 };
00050 
00051 struct _BamfViewPrivate
00052 {
00053   BamfDBusItemView *dbus_iface;
00054   char * name;
00055   char * path;
00056   GList * children;
00057   GList * parents;
00058   gboolean closed;
00059 };
00060 
00061 static void
00062 bamf_view_active_changed (BamfView *view, gboolean active)
00063 {
00064   g_return_if_fail (BAMF_IS_VIEW (view));
00065 
00066   gboolean emit = TRUE;
00067   if (BAMF_VIEW_GET_CLASS (view)->active_changed)
00068     {
00069       emit = !BAMF_VIEW_GET_CLASS (view)->active_changed (view, active);
00070     }
00071 
00072   if (emit)
00073     g_signal_emit_by_name (view, "active-changed", active);
00074 }
00075 
00076 static void
00077 bamf_view_name_changed (BamfView *view,
00078                         const gchar *old_name,
00079                         const gchar *new_name)
00080 {
00081   g_return_if_fail (BAMF_IS_VIEW (view));
00082 
00083   g_signal_emit_by_name (view, "name-changed", old_name, new_name);
00084 
00085   if (view->priv->name)
00086     g_free (view->priv->name);
00087 
00088   view->priv->name = g_strdup (new_name);
00089 }
00090 
00091 static void
00092 bamf_view_user_visible_changed (BamfView *view, gboolean user_visible)
00093 {
00094   g_return_if_fail (BAMF_IS_VIEW (view));
00095 
00096   gboolean emit = TRUE;
00097   if (BAMF_VIEW_GET_CLASS (view)->user_visible_changed)
00098     {
00099       emit = !BAMF_VIEW_GET_CLASS (view)->user_visible_changed (view, user_visible);
00100     }
00101 
00102   if (emit)
00103     g_signal_emit_by_name (view, "user-visible-changed", user_visible);
00104 }
00105 
00106 static void
00107 bamf_view_running_changed (BamfView *view, gboolean running)
00108 {
00109   g_return_if_fail (BAMF_IS_VIEW (view));
00110 
00111   gboolean emit = TRUE;
00112   if (BAMF_VIEW_GET_CLASS (view)->running_changed)
00113     {
00114       emit = !BAMF_VIEW_GET_CLASS (view)->running_changed (view, running);
00115     }
00116 
00117   if (emit)
00118     g_signal_emit_by_name (view, "running-changed", running);
00119 }
00120 
00121 static void
00122 bamf_view_urgent_changed (BamfView *view, gboolean urgent)
00123 {
00124   g_return_if_fail (BAMF_IS_VIEW (view));
00125 
00126   gboolean emit = TRUE;
00127   if (BAMF_VIEW_GET_CLASS (view)->urgent_changed)
00128     {
00129       emit = !BAMF_VIEW_GET_CLASS (view)->urgent_changed (view, urgent);
00130     }
00131 
00132   if (emit)
00133     g_signal_emit_by_name (view, "urgent-changed", urgent);
00134 }
00135 
00136 void
00137 bamf_view_close (BamfView *view)
00138 {
00139   BamfViewPrivate *priv;
00140   gboolean emit = TRUE;
00141   GList *l;
00142 
00143   g_return_if_fail (BAMF_IS_VIEW (view));
00144   priv = view->priv;
00145 
00146   if (priv->closed)
00147     return;
00148 
00149   priv->closed = TRUE;
00150 
00151   if (BAMF_VIEW_GET_CLASS (view)->closed)
00152     {
00153       emit = !BAMF_VIEW_GET_CLASS (view)->closed (view);
00154     }
00155 
00156   if (priv->children)
00157     {
00158       for (l = priv->children; l; l = l->next)
00159         {
00160           if (BAMF_IS_VIEW (l->data))
00161             bamf_view_remove_child (view, l->data);
00162         }
00163       g_list_free (priv->children);
00164       priv->children = NULL;
00165     }
00166 
00167   if (emit)
00168     {
00169       g_object_ref (view);
00170       g_signal_emit (view, view_signals[CLOSED_INTERNAL], 0);
00171       g_signal_emit_by_name (view, "closed");
00172       g_object_unref (view);
00173     }
00174 }
00175 
00176 const char *
00177 bamf_view_get_path (BamfView *view)
00178 {
00179   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00180 
00181   return view->priv->path;
00182 }
00183 
00184 GVariant *
00185 bamf_view_get_children_paths (BamfView *view)
00186 {
00187   GVariantBuilder b;
00188   GList *l;
00189 
00190   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00191 
00192   g_variant_builder_init (&b, G_VARIANT_TYPE ("(as)"));
00193   g_variant_builder_open (&b, G_VARIANT_TYPE ("as"));
00194 
00195   for (l = view->priv->children; l; l = l->next)
00196     {
00197       BamfView *child = l->data;
00198       const char *path = bamf_view_get_path (child);
00199 
00200       if (!path)
00201         continue;
00202 
00203       g_variant_builder_add (&b, "s", path);
00204     }
00205 
00206   g_variant_builder_close (&b);
00207 
00208   return g_variant_builder_end (&b);
00209 }
00210 
00211 GList *
00212 bamf_view_get_children (BamfView *view)
00213 {
00214   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00215 
00216   return view->priv->children;
00217 }
00218 
00219 GVariant *
00220 bamf_view_get_parent_paths (BamfView *view)
00221 {
00222   GVariantBuilder b;
00223   GList *l;
00224 
00225   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00226 
00227   g_variant_builder_init (&b, G_VARIANT_TYPE ("(as)"));
00228   g_variant_builder_open (&b, G_VARIANT_TYPE ("as"));
00229 
00230   for (l = view->priv->parents; l; l = l->next)
00231     {
00232       BamfView *parent = l->data;
00233       const char *path = bamf_view_get_path (parent);
00234 
00235       if (!path)
00236         continue;
00237 
00238       g_variant_builder_add (&b, "s", path);
00239     }
00240 
00241   g_variant_builder_close (&b);
00242 
00243   return g_variant_builder_end (&b);
00244 }
00245 
00246 GList *
00247 bamf_view_get_parents (BamfView *view)
00248 {
00249   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00250 
00251   return view->priv->parents;
00252 }
00253 
00254 static void
00255 bamf_view_handle_child_closed (BamfView *child,
00256                                BamfView *view)
00257 {
00258   bamf_view_remove_child (view, child);
00259 }
00260 
00261 void
00262 bamf_view_add_child (BamfView *view,
00263                      BamfView *child)
00264 {
00265   const char * added;
00266 
00267   g_return_if_fail (BAMF_IS_VIEW (view));
00268   g_return_if_fail (BAMF_IS_VIEW (child));
00269 
00270   g_signal_connect (G_OBJECT (child), "closed-internal",
00271                     (GCallback) bamf_view_handle_child_closed, view);
00272 
00273   /* Make sure our parent child lists are ok, pay attention to whose list you add parents to */
00274   view->priv->children = g_list_prepend (view->priv->children, child);
00275   child->priv->parents = g_list_prepend (child->priv->parents, view);
00276 
00277   // Do this by hand so we can pass and object instead of a string
00278   if (BAMF_VIEW_GET_CLASS (view)->child_added)
00279     BAMF_VIEW_GET_CLASS (view)->child_added (view, child);
00280 
00281   added = bamf_view_get_path (child);
00282   g_signal_emit_by_name (view, "child-added", added);
00283 }
00284 
00285 void
00286 bamf_view_remove_child (BamfView *view,
00287                         BamfView *child)
00288 {
00289   const char * removed;
00290 
00291   g_return_if_fail (BAMF_IS_VIEW (view));
00292   g_return_if_fail (BAMF_IS_VIEW (child));
00293 
00294   g_signal_handlers_disconnect_by_func (child, bamf_view_handle_child_closed, view);
00295 
00296   /* Make sure our parent child lists are ok, pay attention to whose list you add parents to */
00297   view->priv->children = g_list_remove (view->priv->children, child);
00298   child->priv->parents = g_list_remove (child->priv->parents, view);
00299 
00300   removed = bamf_view_get_path (child);
00301   g_signal_emit_by_name (view, "child-removed", removed);
00302 
00303   // Do this by hand so we can pass and object instead of a string
00304   if (BAMF_VIEW_GET_CLASS (view)->child_removed)
00305     BAMF_VIEW_GET_CLASS (view)->child_removed (view, child);
00306 }
00307 
00308 gboolean
00309 bamf_view_is_active (BamfView *view)
00310 {
00311   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00312 
00313   return bamf_dbus_item_view_get_active (view->priv->dbus_iface);
00314 }
00315 
00316 void
00317 bamf_view_set_active (BamfView *view,
00318                       gboolean active)
00319 {
00320   g_return_if_fail (BAMF_IS_VIEW (view));
00321 
00322   if (active == bamf_view_is_active (view))
00323     return;
00324 
00325   bamf_dbus_item_view_set_active (view->priv->dbus_iface, active);
00326   bamf_view_active_changed (view, active);
00327 }
00328 
00329 gboolean
00330 bamf_view_is_urgent (BamfView *view)
00331 {
00332   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00333 
00334   return bamf_dbus_item_view_get_urgent (view->priv->dbus_iface);
00335 }
00336 
00337 void
00338 bamf_view_set_urgent (BamfView *view,
00339                        gboolean urgent)
00340 {
00341   g_return_if_fail (BAMF_IS_VIEW (view));
00342 
00343   if (urgent == bamf_view_is_urgent (view))
00344     return;
00345 
00346   bamf_dbus_item_view_set_urgent (view->priv->dbus_iface, urgent);
00347   bamf_view_urgent_changed (view, urgent);
00348 }
00349 
00350 gboolean
00351 bamf_view_is_running (BamfView *view)
00352 {
00353   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00354 
00355   return bamf_dbus_item_view_get_running (view->priv->dbus_iface);
00356 }
00357 
00358 void
00359 bamf_view_set_running (BamfView *view,
00360                        gboolean running)
00361 {
00362   g_return_if_fail (BAMF_IS_VIEW (view));
00363 
00364   if (running == bamf_view_is_running (view))
00365     return;
00366 
00367   bamf_dbus_item_view_set_running (view->priv->dbus_iface, running);
00368   bamf_view_running_changed (view, running);
00369 }
00370 
00371 gboolean
00372 bamf_view_user_visible (BamfView *view)
00373 {
00374   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00375 
00376   return bamf_dbus_item_view_get_user_visible (view->priv->dbus_iface);
00377 }
00378 
00379 void
00380 bamf_view_set_user_visible (BamfView *view, gboolean user_visible)
00381 {
00382   g_return_if_fail (BAMF_IS_VIEW (view));
00383 
00384   if (user_visible == bamf_view_user_visible (view))
00385     return;
00386 
00387   bamf_dbus_item_view_set_user_visible (view->priv->dbus_iface, user_visible);
00388   bamf_view_user_visible_changed (view, user_visible);
00389 }
00390 
00391 const char *
00392 bamf_view_get_icon (BamfView *view)
00393 {
00394   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00395 
00396   if (BAMF_VIEW_GET_CLASS (view)->get_icon)
00397     return BAMF_VIEW_GET_CLASS (view)->get_icon (view);
00398 
00399   return NULL;
00400 }
00401 
00402 const char *
00403 bamf_view_get_name (BamfView *view)
00404 {
00405   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00406 
00407   if (BAMF_VIEW_GET_CLASS (view)->get_name)
00408     return BAMF_VIEW_GET_CLASS (view)->get_name (view);
00409 
00410   return view->priv->name;
00411 }
00412 
00413 void
00414 bamf_view_set_name (BamfView *view,
00415                     const char * name)
00416 {
00417   g_return_if_fail (BAMF_IS_VIEW (view));
00418 
00419   if (!g_strcmp0 (name, view->priv->name))
00420     return;
00421 
00422   bamf_view_name_changed (view, view->priv->name, name);
00423 }
00424 
00425 const char *
00426 bamf_view_get_view_type (BamfView *view)
00427 {
00428   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00429 
00430   if (BAMF_VIEW_GET_CLASS (view)->view_type)
00431     return BAMF_VIEW_GET_CLASS (view)->view_type (view);
00432 
00433   return "view";
00434 }
00435 
00436 char *
00437 bamf_view_get_stable_bus_name (BamfView *view)
00438 {
00439   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00440 
00441   if (BAMF_VIEW_GET_CLASS (view)->stable_bus_name)
00442     return BAMF_VIEW_GET_CLASS (view)->stable_bus_name (view);
00443     
00444   return g_strdup_printf ("view%p", view);
00445 }
00446 
00447 const char *
00448 bamf_view_export_on_bus (BamfView *view, GDBusConnection *connection)
00449 {
00450   char *path = NULL;
00451   GList *ifaces, *l;
00452   GError *error = NULL;
00453 
00454   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00455   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
00456 
00457   if (!view->priv->path)
00458     {
00459       char *stable_name = bamf_view_get_stable_bus_name (view);
00460       path = g_strdup_printf ("%s/%s", BAMF_DBUS_PATH, stable_name);
00461       g_free (stable_name);
00462 
00463       BAMF_VIEW_GET_CLASS (view)->names = g_list_prepend (BAMF_VIEW_GET_CLASS (view)->names, path);
00464       view->priv->path = path;
00465 
00466       ifaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (view));
00467 
00468       /* The dbus object interface list is in reversed order, we try to export
00469        * the interfaces in bottom to top order (BamfView should be the first) */
00470       for (l = g_list_last(ifaces); l; l = l->prev)
00471         {
00472           g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (l->data),
00473                                             connection, path, &error);
00474         }
00475 
00476       if (error)
00477         {
00478           g_critical ("Can't register BAMF view: %s", error->message);
00479           g_error_free (error);
00480         }
00481       else
00482         {
00483           g_signal_emit (view, view_signals[EXPORTED], 0);
00484         }
00485 
00486       g_list_free_full (ifaces, g_object_unref);
00487     }
00488 
00489   return view->priv->path;
00490 }
00491 
00492 gboolean
00493 bamf_view_is_on_bus (BamfView *view)
00494 {
00495   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00496   GDBusInterfaceSkeleton *dbus_iface;
00497   const gchar *exported_path;
00498 
00499   dbus_iface = G_DBUS_INTERFACE_SKELETON (view->priv->dbus_iface);
00500   exported_path = g_dbus_interface_skeleton_get_object_path (dbus_iface);
00501 
00502   return (view->priv->path != NULL && exported_path != NULL);
00503 }
00504 
00505 static void
00506 on_view_active_changed (BamfView *view, gboolean active, gpointer _not_used)
00507 {
00508   g_return_if_fail (BAMF_IS_VIEW (view));
00509   g_signal_emit_by_name (view->priv->dbus_iface, "active-changed", active);
00510 }
00511 
00512 static void
00513 on_view_running_changed (BamfView *view, gboolean running, gpointer _not_used)
00514 {
00515   g_return_if_fail (BAMF_IS_VIEW (view));
00516   g_signal_emit_by_name (view->priv->dbus_iface, "running-changed", running);
00517 }
00518 
00519 static void
00520 on_view_urgent_changed (BamfView *view, gboolean urgent, gpointer _not_used)
00521 {
00522   g_return_if_fail (BAMF_IS_VIEW (view));
00523   g_signal_emit_by_name (view->priv->dbus_iface, "urgent-changed", urgent);
00524 }
00525 
00526 static void
00527 on_view_user_visible_changed (BamfView *view, gboolean user_visible, gpointer _not_used)
00528 {
00529   g_return_if_fail (BAMF_IS_VIEW (view));
00530   g_signal_emit_by_name (view->priv->dbus_iface, "user-visible-changed", user_visible);
00531 }
00532 
00533 static void
00534 on_view_name_changed (BamfView *view, const gchar *old_name, const gchar *new_name, gpointer _not_used)
00535 {
00536   g_return_if_fail (BAMF_IS_VIEW (view));
00537   g_signal_emit_by_name (view->priv->dbus_iface, "name-changed",
00538                          old_name ? old_name : "", new_name ? new_name : "");
00539 }
00540 
00541 static void
00542 on_view_child_added (BamfView *view, const gchar *child_path, gpointer _not_used)
00543 {
00544   g_return_if_fail (BAMF_IS_VIEW (view));
00545   g_signal_emit_by_name (view->priv->dbus_iface, "child-added",
00546                          child_path ? child_path : "");
00547 }
00548 
00549 static void
00550 on_view_child_removed (BamfView *view, const gchar *child_path, gpointer _not_used)
00551 {
00552   g_return_if_fail (BAMF_IS_VIEW (view));
00553   g_signal_emit_by_name (view->priv->dbus_iface, "child-removed",
00554                          child_path ? child_path : "");
00555 }
00556 
00557 static void
00558 on_view_closed (BamfView *view, gpointer _not_used)
00559 {
00560   g_return_if_fail (BAMF_IS_VIEW (view));
00561   g_signal_emit_by_name (view->priv->dbus_iface, "closed");
00562 }
00563 
00564 static gboolean
00565 on_dbus_handle_view_type (BamfDBusItemView *interface,
00566                           GDBusMethodInvocation *invocation,
00567                           BamfView *view)
00568 {
00569   const char *type = bamf_view_get_view_type (view);
00570   g_dbus_method_invocation_return_value (invocation,
00571                                          g_variant_new ("(s)", type));
00572 
00573   return TRUE;
00574 }
00575 
00576 static gboolean
00577 on_dbus_handle_user_visible (BamfDBusItemView *interface,
00578                              GDBusMethodInvocation *invocation,
00579                              BamfView *view)
00580 {
00581   gboolean user_visible = bamf_view_user_visible (view);
00582   g_dbus_method_invocation_return_value (invocation,
00583                                          g_variant_new ("(b)", user_visible));
00584 
00585   return TRUE;
00586 }
00587 
00588 static gboolean
00589 on_dbus_handle_icon (BamfDBusItemView *interface,
00590                      GDBusMethodInvocation *invocation,
00591                      BamfView *view)
00592 {
00593   const char *icon = bamf_view_get_icon (view);
00594   g_dbus_method_invocation_return_value (invocation,
00595                                          g_variant_new ("(s)", icon ? icon : ""));
00596 
00597   return TRUE;
00598 }
00599 
00600 static gboolean
00601 on_dbus_handle_name (BamfDBusItemView *interface,
00602                      GDBusMethodInvocation *invocation,
00603                      BamfView *view)
00604 {
00605   const char *name = bamf_view_get_name (view);
00606   g_dbus_method_invocation_return_value (invocation,
00607                                          g_variant_new ("(s)", name ? name : ""));
00608 
00609   return TRUE;
00610 }
00611 
00612 static gboolean
00613 on_dbus_handle_is_urgent (BamfDBusItemView *interface,
00614                           GDBusMethodInvocation *invocation,
00615                           BamfView *view)
00616 {
00617   gboolean is_urgent = bamf_view_is_urgent (view);
00618   g_dbus_method_invocation_return_value (invocation,
00619                                          g_variant_new ("(b)", is_urgent));
00620 
00621   return TRUE;
00622 }
00623 
00624 static gboolean
00625 on_dbus_handle_is_running (BamfDBusItemView *interface,
00626                            GDBusMethodInvocation *invocation,
00627                            BamfView *view)
00628 {
00629   gboolean is_running = bamf_view_is_running (view);
00630   g_dbus_method_invocation_return_value (invocation,
00631                                          g_variant_new ("(b)", is_running));
00632 
00633   return TRUE;
00634 }
00635 
00636 static gboolean
00637 on_dbus_handle_is_active (BamfDBusItemView *interface,
00638                           GDBusMethodInvocation *invocation,
00639                           BamfView *view)
00640 {
00641   gboolean is_active = bamf_view_is_active (view);
00642   g_dbus_method_invocation_return_value (invocation,
00643                                          g_variant_new ("(b)", is_active));
00644 
00645   return TRUE;
00646 }
00647 
00648 static gboolean
00649 on_dbus_handle_parents (BamfDBusItemView *interface,
00650                         GDBusMethodInvocation *invocation,
00651                         BamfView *view)
00652 {
00653   GVariant *parents = bamf_view_get_parent_paths (view);
00654   g_dbus_method_invocation_return_value (invocation, parents);
00655 
00656   return TRUE;
00657 }
00658 
00659 static gboolean
00660 on_dbus_handle_children (BamfDBusItemView *interface,
00661                          GDBusMethodInvocation *invocation,
00662                          BamfView *view)
00663 {
00664   GVariant *children = bamf_view_get_children_paths (view);
00665   g_dbus_method_invocation_return_value (invocation, children);
00666 
00667   return TRUE;
00668 }
00669 
00670 static void
00671 bamf_view_dispose (GObject *object)
00672 {
00673   BamfView *view = BAMF_VIEW (object);
00674   BamfViewPrivate *priv = view->priv;
00675   GList *ifaces, *l;
00676 
00677   ifaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (view));
00678 
00679   for (l = ifaces; l; l = l->next)
00680     {
00681       GDBusInterfaceSkeleton *iface = G_DBUS_INTERFACE_SKELETON (l->data);
00682 
00683       if (g_dbus_interface_skeleton_get_object_path (iface))
00684         g_dbus_interface_skeleton_unexport (iface);
00685     }
00686 
00687   g_list_free_full (ifaces, g_object_unref);
00688 
00689   if (priv->name)
00690     {
00691       g_free (priv->name);
00692       priv->name = NULL;
00693     }
00694 
00695   if (priv->path)
00696     {
00697       g_free (priv->path);
00698       priv->path = NULL;
00699     }
00700 
00701   if (priv->children)
00702     {
00703       g_list_free (priv->children);
00704       priv->children = NULL;
00705     }
00706 
00707   if (priv->parents)
00708     {
00709       g_list_free (priv->parents);
00710       priv->parents = NULL;
00711     }
00712 
00713   G_OBJECT_CLASS (bamf_view_parent_class)->dispose (object);
00714 }
00715 
00716 static void
00717 bamf_view_finalize (GObject *object)
00718 {
00719   BamfView *view = BAMF_VIEW (object);
00720 
00721   g_object_unref (view->priv->dbus_iface);
00722 
00723   G_OBJECT_CLASS (bamf_view_parent_class)->finalize (object);
00724 }
00725 
00726 static void
00727 bamf_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
00728 {
00729   BamfView *view = BAMF_VIEW (object);
00730 
00731   switch (property_id)
00732     {
00733       case PROP_ACTIVE:
00734         g_value_set_boolean (value, bamf_view_is_active (view));
00735         break;
00736       case PROP_URGENT:
00737         g_value_set_boolean (value, bamf_view_is_urgent (view));
00738         break;
00739       case PROP_USER_VISIBLE:
00740         g_value_set_boolean (value, bamf_view_user_visible (view));
00741         break;
00742       case PROP_RUNNING:
00743         g_value_set_boolean (value, bamf_view_is_running (view));
00744         break;
00745       default:
00746         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
00747     }
00748 }
00749 
00750 static void
00751 bamf_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
00752 {
00753   switch (property_id)
00754     {
00755       default:
00756         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
00757     }
00758 }
00759 
00760 static void
00761 bamf_view_init (BamfView * self)
00762 {
00763   self->priv = BAMF_VIEW_GET_PRIVATE (self);
00764 
00765   /* Initializing the dbus interface */
00766   self->priv->dbus_iface = bamf_dbus_item_view_skeleton_new ();
00767 
00768   /* We need to connect to the object own signals to redirect them to the dbus
00769    * interface                                                                */
00770   g_signal_connect (self, "active-changed", G_CALLBACK (on_view_active_changed), NULL);
00771   g_signal_connect (self, "running-changed", G_CALLBACK (on_view_running_changed), NULL);
00772   g_signal_connect (self, "urgent-changed", G_CALLBACK (on_view_urgent_changed), NULL);
00773   g_signal_connect (self, "user-visible-changed", G_CALLBACK (on_view_user_visible_changed), NULL);
00774   g_signal_connect (self, "name-changed", G_CALLBACK (on_view_name_changed), NULL);
00775   g_signal_connect (self, "child-added", G_CALLBACK (on_view_child_added), NULL);
00776   g_signal_connect (self, "child-removed", G_CALLBACK (on_view_child_removed), NULL);
00777   g_signal_connect (self, "closed", G_CALLBACK (on_view_closed), NULL);
00778 
00779   /* Registering signal callbacks to reply to dbus method calls */
00780   g_signal_connect (self->priv->dbus_iface, "handle-view-type",
00781                     G_CALLBACK (on_dbus_handle_view_type), self);
00782 
00783   g_signal_connect (self->priv->dbus_iface, "handle-user-visible",
00784                     G_CALLBACK (on_dbus_handle_user_visible), self);
00785 
00786   g_signal_connect (self->priv->dbus_iface, "handle-icon",
00787                     G_CALLBACK (on_dbus_handle_icon), self);
00788 
00789   g_signal_connect (self->priv->dbus_iface, "handle-name",
00790                     G_CALLBACK (on_dbus_handle_name), self);
00791 
00792   g_signal_connect (self->priv->dbus_iface, "handle-is-urgent",
00793                     G_CALLBACK (on_dbus_handle_is_urgent), self);
00794 
00795   g_signal_connect (self->priv->dbus_iface, "handle-is-running",
00796                     G_CALLBACK (on_dbus_handle_is_running), self);
00797 
00798   g_signal_connect (self->priv->dbus_iface, "handle-is-active",
00799                     G_CALLBACK (on_dbus_handle_is_active), self);
00800 
00801   g_signal_connect (self->priv->dbus_iface, "handle-parents",
00802                     G_CALLBACK (on_dbus_handle_parents), self);
00803 
00804   g_signal_connect (self->priv->dbus_iface, "handle-children",
00805                     G_CALLBACK (on_dbus_handle_children), self);
00806 
00807   /* Setting the interface for the dbus object */
00808   bamf_dbus_item_object_skeleton_set_view (BAMF_DBUS_ITEM_OBJECT_SKELETON (self),
00809                                            self->priv->dbus_iface);
00810 }
00811 
00812 static void
00813 bamf_view_dbus_view_iface_init (BamfDBusItemViewIface *iface)
00814 {
00815 }
00816 
00817 static void
00818 bamf_view_class_init (BamfViewClass * klass)
00819 {
00820   GObjectClass *object_class = G_OBJECT_CLASS (klass);
00821 
00822   object_class->dispose = bamf_view_dispose;
00823   object_class->finalize = bamf_view_finalize;
00824   object_class->get_property = bamf_view_get_property;
00825   object_class->set_property = bamf_view_set_property;
00826 
00827   g_type_class_add_private (klass, sizeof (BamfViewPrivate));
00828 
00829   /* Overriding the properties defined in the interface, this is needed
00830    * but we actually don't use these properties, as we act like a proxy       */
00831   g_object_class_override_property (object_class, PROP_ACTIVE, "active");
00832   g_object_class_override_property (object_class, PROP_URGENT, "urgent");
00833   g_object_class_override_property (object_class, PROP_RUNNING, "running");
00834   g_object_class_override_property (object_class, PROP_USER_VISIBLE, "user-visible");
00835 
00836   view_signals [CLOSED_INTERNAL] =
00837     g_signal_new ("closed-internal",
00838                   G_OBJECT_CLASS_TYPE (klass),
00839                   0,
00840                   0, NULL, NULL,
00841                   g_cclosure_marshal_VOID__VOID,
00842                   G_TYPE_NONE, 0);
00843 
00844   view_signals [EXPORTED] =
00845     g_signal_new ("exported",
00846                   G_OBJECT_CLASS_TYPE (klass),
00847                   0,
00848                   0, NULL, NULL,
00849                   g_cclosure_marshal_VOID__VOID,
00850                   G_TYPE_NONE, 0);
00851 }