Back to index

indicator-appmenu  12.10.0
hudindicatorsource.c
Go to the documentation of this file.
00001 /*
00002  * Copyright © 2012 Canonical Ltd.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * 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, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranties of
00010  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
00011  * PURPOSE.  See the GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License along
00014  * with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Authors: Ryan Lortie <desrt@desrt.ca>
00017  *          Ted Gould <ted@canonical.com>
00018  */
00019 
00020 #include "hudindicatorsource.h"
00021 
00022 #include <glib/gi18n.h>
00023 #include <gio/gio.h>
00024 
00025 #include "hudsettings.h"
00026 #include "huddbusmenucollector.h"
00027 #include "hudsource.h"
00028 
00045 typedef struct
00046 {
00047   const gchar *dbus_name;
00048   const gchar *dbus_menu_path;
00049   const gchar *indicator_name;
00050   const gchar *user_visible_name;
00051   const gchar *icon;
00052 } IndicatorInfo;
00053 
00054 static const IndicatorInfo indicator_info[] = {
00055   {
00056     .dbus_name         = "com.canonical.indicator.datetime",
00057     .dbus_menu_path    = "/com/canonical/indicator/datetime/menu",
00058     .indicator_name    = "indicator-datetime",
00059     .user_visible_name = N_("Date"),
00060     .icon              = "office-calendar"
00061   },
00062   {
00063     .dbus_name         = "com.canonical.indicator.session",
00064     .dbus_menu_path    = "/com/canonical/indicator/session/menu",
00065     .indicator_name    = "indicator-session-device",
00066     .user_visible_name = N_("Device"),
00067     .icon              = "system-devices-panel"
00068   },
00069   {
00070     .dbus_name         = "com.canonical.indicator.session",
00071     .dbus_menu_path    = "/com/canonical/indicator/users/menu",
00072     .indicator_name    = "indicator-session-user",
00073     .user_visible_name = N_("Users"),
00074     .icon              = "avatar-default"
00075   },
00076   {
00077     .dbus_name         = "com.canonical.indicator.sound",
00078     .dbus_menu_path    = "/com/canonical/indicator/sound/menu",
00079     .indicator_name    = "indicator-sound",
00080     .user_visible_name = N_("Sound"),
00081     .icon              = "audio-volume-high-panel"
00082   },
00083   {
00084     .dbus_name         = "com.canonical.indicator.messages",
00085     .dbus_menu_path    = "/com/canonical/indicator/messages/menu",
00086     .indicator_name    = "indicator-messages",
00087     .user_visible_name = N_("Messages"),
00088     .icon              = "indicator-messages"
00089   }
00090 };
00091 
00092 typedef struct
00093 {
00094   const IndicatorInfo *info;
00095   HudIndicatorSource *source;
00096   HudSource *collector;
00097 } HudIndicatorSourceIndicator;
00098 
00099 struct _HudIndicatorSource
00100 {
00101   GObject parent_instance;
00102 
00103   HudIndicatorSourceIndicator *indicators;
00104   gint n_indicators;
00105   gint use_count;
00106 };
00107 
00108 typedef GObjectClass HudIndicatorSourceClass;
00109 
00110 static void hud_indicator_source_iface_init (HudSourceInterface *iface);
00111 G_DEFINE_TYPE_WITH_CODE (HudIndicatorSource, hud_indicator_source, G_TYPE_OBJECT,
00112                          G_IMPLEMENT_INTERFACE (HUD_TYPE_SOURCE, hud_indicator_source_iface_init))
00113 
00114 static void
00115 hud_indicator_source_use (HudSource *hud_source)
00116 {
00117   HudIndicatorSource *source = HUD_INDICATOR_SOURCE (hud_source);
00118   gint i;
00119 
00120   if (source->use_count == 0)
00121     {
00122       for (i = 0; i < source->n_indicators; i++)
00123         if (source->indicators[i].collector)
00124           hud_source_use (source->indicators[i].collector);
00125     }
00126 
00127   source->use_count++;
00128 }
00129 
00130 static void
00131 hud_indicator_source_unuse (HudSource *hud_source)
00132 {
00133   HudIndicatorSource *source = HUD_INDICATOR_SOURCE (hud_source);
00134   gint i;
00135 
00136   g_return_if_fail (source->use_count > 0);
00137 
00138   source->use_count--;
00139 
00140   if (source->use_count == 0)
00141     {
00142       for (i = 0; i < source->n_indicators; i++)
00143         if (source->indicators[i].collector)
00144           hud_source_unuse (source->indicators[i].collector);
00145     }
00146 }
00147 
00148 static void
00149 hud_indicator_source_search (HudSource    *hud_source,
00150                              GPtrArray    *results_array,
00151                              HudTokenList *search_string)
00152 {
00153   HudIndicatorSource *source = HUD_INDICATOR_SOURCE (hud_source);
00154   gint i;
00155 
00156   for (i = 0; i < source->n_indicators; i++)
00157     if (source->indicators[i].collector)
00158       hud_source_search (source->indicators[i].collector, results_array, search_string);
00159 }
00160 
00161 static void
00162 hud_indicator_source_finalize (GObject *object)
00163 {
00164   g_assert_not_reached ();
00165 }
00166 
00167 static void
00168 hud_indicator_source_collector_changed (HudSource *source,
00169                                         gpointer   user_data)
00170 {
00171   HudIndicatorSourceIndicator *indicator = user_data;
00172 
00173   hud_source_changed (HUD_SOURCE (indicator->source));
00174 }
00175 
00176 static void
00177 hud_indicator_source_name_appeared (GDBusConnection *connection,
00178                                     const gchar     *name,
00179                                     const gchar     *name_owner,
00180                                     gpointer         user_data)
00181 {
00182   HudIndicatorSourceIndicator *indicator = user_data;
00183   HudDbusmenuCollector *collector;
00184 
00185   collector = hud_dbusmenu_collector_new_for_endpoint (indicator->info->indicator_name,
00186                                                        _(indicator->info->user_visible_name),
00187                                                        indicator->info->icon,
00188                                                        hud_settings.indicator_penalty,
00189                                                        name_owner, indicator->info->dbus_menu_path);
00190   g_signal_connect (collector, "changed", G_CALLBACK (hud_indicator_source_collector_changed), indicator);
00191   indicator->collector = HUD_SOURCE (collector);
00192 
00193   /* Set initial use count on new indicator if query is active. */
00194   if (indicator->source->use_count)
00195     hud_source_use (indicator->collector);
00196 
00197   hud_source_changed (HUD_SOURCE (indicator->source));
00198 }
00199 
00200 static void
00201 hud_indicator_source_name_vanished (GDBusConnection *connection,
00202                                     const gchar     *name,
00203                                     gpointer         user_data)
00204 {
00205   HudIndicatorSourceIndicator *indicator = user_data;
00206 
00207   if (indicator->collector)
00208     {
00209       g_signal_handlers_disconnect_by_func (indicator->collector, hud_indicator_source_collector_changed, indicator);
00210       /* Drop our use count on dying indicator (if any) */
00211       if (indicator->source->use_count)
00212         hud_source_unuse (indicator->collector);
00213       g_clear_object (&indicator->collector);
00214     }
00215 
00216   hud_source_changed (HUD_SOURCE (indicator->source));
00217 }
00218 
00219 static void
00220 hud_indicator_source_init (HudIndicatorSource *source)
00221 {
00222   gint i;
00223 
00224   source->n_indicators = G_N_ELEMENTS (indicator_info);
00225   source->indicators = g_new0 (HudIndicatorSourceIndicator, source->n_indicators);
00226 
00227   for (i = 0; i < source->n_indicators; i++)
00228     {
00229       HudIndicatorSourceIndicator *indicator = &source->indicators[i];
00230 
00231       indicator->info = &indicator_info[i];
00232       indicator->source = source;
00233 
00234       g_bus_watch_name (G_BUS_TYPE_SESSION, indicator->info->dbus_name, G_BUS_NAME_WATCHER_FLAGS_NONE,
00235                         hud_indicator_source_name_appeared, hud_indicator_source_name_vanished, indicator, NULL);
00236     }
00237 }
00238 
00239 static void
00240 hud_indicator_source_iface_init (HudSourceInterface *iface)
00241 {
00242   iface->use = hud_indicator_source_use;
00243   iface->unuse = hud_indicator_source_unuse;
00244   iface->search = hud_indicator_source_search;
00245 }
00246 
00247 static void
00248 hud_indicator_source_class_init (HudIndicatorSourceClass *class)
00249 {
00250   class->finalize = hud_indicator_source_finalize;
00251 }
00252 
00260 HudIndicatorSource *
00261 hud_indicator_source_new (void)
00262 {
00263   return g_object_new (HUD_TYPE_INDICATOR_SOURCE, NULL);
00264 }