Back to index

unity  6.0.0
panel-root-accessible.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 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: Rodrigo Moya <rodrigo.moya@canonical.com>
00017  */
00018 
00019 #include <glib/gi18n.h>
00020 #include "panel-indicator-accessible.h"
00021 #include "panel-root-accessible.h"
00022 #include "panel-service.h"
00023 
00024 G_DEFINE_TYPE(PanelRootAccessible, panel_root_accessible, ATK_TYPE_OBJECT)
00025 
00026 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_ROOT_ACCESSIBLE, PanelRootAccessiblePrivate))
00027 
00028 /* AtkObject methods */
00029 static void       panel_root_accessible_initialize     (AtkObject *accessible, gpointer data);
00030 static gint       panel_root_accessible_get_n_children (AtkObject *accessible);
00031 static AtkObject *panel_root_accessible_ref_child      (AtkObject *accessible, gint i);
00032 static AtkObject *panel_root_accessible_get_parent     (AtkObject *accessible);
00033 
00034 struct _PanelRootAccessiblePrivate
00035 {
00036   PanelService *service;
00037   GSList *a11y_children;
00038 };
00039 
00040 static void
00041 panel_root_accessible_finalize (GObject *object)
00042 {
00043   PanelRootAccessible *root = PANEL_ROOT_ACCESSIBLE (object);
00044 
00045   if ((root->priv != NULL) && (root->priv->a11y_children != NULL))
00046     {
00047       g_slist_free_full(root->priv->a11y_children, g_object_unref);
00048       root->priv->a11y_children = NULL;
00049     }
00050 }
00051 
00052 static void
00053 panel_root_accessible_class_init (PanelRootAccessibleClass *klass)
00054 {
00055   GObjectClass *object_class;
00056   AtkObjectClass *atk_class;
00057 
00058   /* GObject */
00059   object_class = G_OBJECT_CLASS (klass);
00060   object_class->finalize = panel_root_accessible_finalize;
00061 
00062   /* AtkObject */
00063   atk_class = ATK_OBJECT_CLASS (klass);
00064   atk_class->initialize = panel_root_accessible_initialize;
00065   atk_class->get_n_children = panel_root_accessible_get_n_children;
00066   atk_class->ref_child = panel_root_accessible_ref_child;
00067   atk_class->get_parent = panel_root_accessible_get_parent;
00068 
00069   g_type_class_add_private (object_class, sizeof (PanelRootAccessiblePrivate));
00070 }
00071 
00072 static void
00073 panel_root_accessible_init (PanelRootAccessible *root)
00074 {
00075   root->priv = GET_PRIVATE (root);
00076   root->priv->a11y_children = NULL;
00077   root->priv->service = panel_service_get_default ();
00078 }
00079 
00080 AtkObject *
00081 panel_root_accessible_new (void)
00082 {
00083   AtkObject *accessible;
00084 
00085   accessible = ATK_OBJECT (g_object_new (PANEL_TYPE_ROOT_ACCESSIBLE, NULL));
00086   atk_object_initialize (accessible, NULL);
00087 
00088   return accessible;
00089 }
00090 
00091 static void
00092 on_indicator_removed (gpointer *data, GObject *removed_indicator)
00093 {
00094   PanelRootAccessible *root = data[0];
00095   AtkObject *child = data[1];
00096 
00097   g_return_if_fail (PANEL_IS_ROOT_ACCESSIBLE (root));
00098   g_return_if_fail (ATK_IS_OBJECT (child));
00099 
00100   gint index = g_slist_index (root->priv->a11y_children, child);
00101   if (index >= 0)
00102     {
00103       root->priv->a11y_children = g_slist_remove (root->priv->a11y_children, child);
00104       g_signal_emit_by_name (root, "children-changed::remove", index, child);
00105       g_object_unref (child);
00106     }
00107 
00108   g_free (data);
00109 }
00110 
00111 /* Implementation of AtkObject methods */
00112 
00113 static void
00114 panel_root_accessible_initialize (AtkObject *accessible, gpointer data)
00115 {
00116   gint n_children, i;
00117   PanelRootAccessible *root = PANEL_ROOT_ACCESSIBLE (accessible);
00118 
00119   g_return_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible));
00120 
00121   ATK_OBJECT_CLASS (panel_root_accessible_parent_class)->initialize (accessible, data);
00122 
00123   accessible->role = ATK_ROLE_APPLICATION;
00124   atk_object_set_name (accessible, g_get_prgname ());
00125   atk_object_set_parent (accessible, NULL);
00126 
00127   /* Retrieve all indicators and create their accessible objects */
00128   n_children = panel_service_get_n_indicators (root->priv->service);
00129   for (i = 0; i < n_children; i++)
00130     {
00131       IndicatorObject *indicator;
00132 
00133       indicator = panel_service_get_indicator_nth (root->priv->service, i);
00134       if (INDICATOR_IS_OBJECT (indicator))
00135         {
00136           AtkObject *child;
00137           gpointer *weak_data;
00138 
00139           child = panel_indicator_accessible_new (indicator);
00140           /* FIXME: use proper signals once we support dynamic adding/removing
00141            * of indicators */
00142           weak_data = g_new0 (gpointer, 2);
00143           weak_data[0] = root;
00144           weak_data[1] = child;
00145           g_object_weak_ref (G_OBJECT (indicator), 
00146               (GWeakNotify) on_indicator_removed, weak_data);
00147 
00148           atk_object_set_parent (child, accessible);
00149           root->priv->a11y_children = g_slist_append (root->priv->a11y_children, child);
00150         }
00151     }
00152 }
00153 
00154 static gint
00155 panel_root_accessible_get_n_children (AtkObject *accessible)
00156 {
00157   PanelRootAccessible *root = PANEL_ROOT_ACCESSIBLE (accessible);
00158 
00159   g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), 0);
00160 
00161   return g_slist_length (root->priv->a11y_children);
00162 }
00163 
00164 static AtkObject *
00165 panel_root_accessible_ref_child (AtkObject *accessible, gint i)
00166 {
00167   PanelRootAccessible *root = PANEL_ROOT_ACCESSIBLE (accessible);
00168 
00169   g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), NULL);
00170 
00171   return g_object_ref (g_slist_nth_data (root->priv->a11y_children, i));
00172 }
00173 
00174 static AtkObject *
00175 panel_root_accessible_get_parent (AtkObject *accessible)
00176 {
00177   g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), NULL);
00178 
00179   return NULL;
00180 }