Back to index

unity  6.0.0
panel-main.c
Go to the documentation of this file.
00001 // -*- Mode: C; tab-width:2; indent-tabs-mode: t; c-basic-offset: 2 -*-
00002 /*
00003  * Copyright (C) 2010 Canonical Ltd
00004  *
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 3 as
00007  * published by the Free Software Foundation.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  *
00017  * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
00018  *              Rodrigo Moya <rodrigo.moya@canonical.com>
00019  */
00020 
00021 #include <glib.h>
00022 #include <gio/gio.h>
00023 #include <gtk/gtk.h>
00024 
00025 #include "panel-a11y.h"
00026 #include "panel-service.h"
00027 
00028 static GDBusNodeInfo *introspection_data = NULL;
00029 
00030 /*
00031  * typedef struct {
00032  *   gchar *indicator_id
00033  *   gchar *entry_id;
00034  *   gchar *label;
00035  *   bool   label_sensitive;
00036  *   bool   label_visible;
00037  *   uint32 icon_hint;
00038  *   gchar *icon_data;
00039  *   bool   icon_sensitive;
00040  *   bool   icon_visible;
00041  *
00042  * } EntryInfo;
00043  */
00044 
00045 static const gchar introspection_xml[] =
00046   "<node>"
00047   "  <interface name='com.canonical.Unity.Panel.Service'>"
00048   ""
00049   "    <method name='Sync'>"
00050   "      <arg type='a(ssssbbusbbi)' name='state' direction='out'/>"
00051   "    </method>"
00052   ""
00053   "    <method name='SyncOne'>"
00054   "      <arg type='s' name='indicator_id' direction='in'/>"
00055   "      <arg type='a(ssssbbusbbi)' name='state' direction='out'/>"
00056   "    </method>"
00057   ""
00058   "    <method name='SyncGeometries'>"
00059   "      <arg type='a(ssiiii)' name='geometries' direction='in'/>"
00060   "    </method>"
00061   ""
00062   "    <method name='ShowEntry'>"
00063   "      <arg type='s' name='entry_id' direction='in'/>"
00064   "      <arg type='u' name='xid' direction='in'/>"
00065   "      <arg type='i' name='x' direction='in'/>"
00066   "      <arg type='i' name='y' direction='in'/>"
00067   "      <arg type='u' name='button' direction='in'/>"
00068   "      <arg type='u' name='timestamp' direction='in'/>"
00069   "    </method>"
00070   ""
00071   "    <method name='ShowAppMenu'>"
00072   "      <arg type='u' name='xid' direction='in'/>"
00073   "      <arg type='i' name='x' direction='in'/>"
00074   "      <arg type='i' name='y' direction='in'/>"
00075   "      <arg type='u' name='timestamp' direction='in'/>"
00076   "    </method>"
00077   ""
00078   "    <method name='SecondaryActivateEntry'>"
00079   "      <arg type='s' name='entry_id' direction='in'/>"
00080   "      <arg type='u' name='timestamp' direction='in'/>"
00081   "    </method>"
00082   ""
00083   "    <method name='ScrollEntry'>"
00084   "      <arg type='s' name='entry_id' direction='in'/>"
00085   "      <arg type='i' name='delta' direction='in'/>"
00086   "    </method>"
00087   ""
00088   "    <signal name='EntryActivated'>"
00089   "     <arg type='s' name='entry_id' />"
00090   "     <arg type='(iiuu)' name='entry_geometry' />"
00091   "    </signal>"
00092   ""
00093   "    <signal name='ReSync'>"
00094   "     <arg type='s' name='indicator_id' />"
00095   "    </signal>"
00096   ""
00097   "    <signal name='EntryActivateRequest'>"
00098   "     <arg type='s' name='entry_id' />"
00099   "    </signal>"
00100   ""
00101   "    <signal name='EntryShowNowChanged'>"
00102   "     <arg type='s' name='entry_id' />"
00103   "     <arg type='b' name='show_now_state' />"
00104   "    </signal>"
00105   ""
00106   "  </interface>"
00107   "</node>";
00108 
00109 #define S_NAME  "com.canonical.Unity.Panel.Service"
00110 #define S_PATH  "/com/canonical/Unity/Panel/Service"
00111 #define S_IFACE "com.canonical.Unity.Panel.Service"
00112 
00113 /* Forwards */
00114 static void
00115 handle_method_call (GDBusConnection       *connection,
00116                     const gchar           *sender,
00117                     const gchar           *object_path,
00118                     const gchar           *interface_name,
00119                     const gchar           *method_name,
00120                     GVariant              *parameters,
00121                     GDBusMethodInvocation *invocation,
00122                     gpointer               user_data);
00123 
00124 
00125 static const GDBusInterfaceVTable interface_vtable =
00126 {
00127   handle_method_call,
00128   NULL,
00129   NULL
00130 };
00131 
00132 
00133 /* Methods */
00134 
00135 static void
00136 handle_method_call (GDBusConnection       *connection,
00137                     const gchar           *sender,
00138                     const gchar           *object_path,
00139                     const gchar           *interface_name,
00140                     const gchar           *method_name,
00141                     GVariant              *parameters,
00142                     GDBusMethodInvocation *invocation,
00143                     gpointer               user_data)
00144 {
00145   PanelService *service = PANEL_SERVICE (user_data);
00146 
00147   if (g_strcmp0 (method_name, "Sync") == 0)
00148     {
00149       g_dbus_method_invocation_return_value (invocation,
00150                                              panel_service_sync (service));
00151     }
00152   else if (g_strcmp0 (method_name, "SyncOne") == 0)
00153     {
00154       gchar *id;
00155       g_variant_get (parameters, "(s)", &id, NULL);
00156       g_dbus_method_invocation_return_value (invocation,
00157                                              panel_service_sync_one (service,
00158                                                                      id));
00159       g_free (id);
00160     }
00161   else if (g_strcmp0 (method_name, "SyncGeometries") == 0)
00162     {
00163       GVariantIter *iter;
00164       gchar *indicator_id, *entry_id;
00165       gint x, y, width, height;
00166 
00167       g_variant_get (parameters, "(a(ssiiii))", &iter);
00168       while (iter && g_variant_iter_loop (iter, "(ssiiii)",
00169                                   &indicator_id,
00170                                   &entry_id,
00171                                   &x,
00172                                   &y,
00173                                   &width,
00174                                   &height))
00175         {
00176           panel_service_sync_geometry (service, indicator_id,
00177                                        entry_id, x, y, width, height);
00178         }
00179 
00180       if (iter) g_variant_iter_free (iter);
00181 
00182       g_dbus_method_invocation_return_value (invocation, NULL);
00183     }
00184   else if (g_strcmp0 (method_name, "ShowEntry") == 0)
00185     {
00186       guint32 xid;
00187       gchar  *entry_id;
00188       gint32  x;
00189       gint32  y;
00190       guint32 button;
00191       guint32 timestamp;
00192       g_variant_get (parameters, "(suiiuu)", &entry_id, &xid, &x, &y, &button, &timestamp, NULL);
00193 
00194       panel_service_show_entry (service, entry_id, xid, x, y, button, timestamp);
00195 
00196       g_dbus_method_invocation_return_value (invocation, NULL);
00197       g_free (entry_id);
00198     }
00199   else if (g_strcmp0 (method_name, "ShowAppMenu") == 0)
00200     {
00201       guint32 xid;
00202       gint32  x;
00203       gint32  y;
00204       guint32 timestamp;
00205       g_variant_get (parameters, "(uiiu)", &xid, &x, &y, &timestamp, NULL);
00206 
00207       panel_service_show_app_menu (service, xid, x, y, timestamp);
00208 
00209       g_dbus_method_invocation_return_value (invocation, NULL);
00210     }
00211   else if (g_strcmp0 (method_name, "SecondaryActivateEntry") == 0)
00212     {
00213       gchar  *entry_id;
00214       guint32 timestamp;
00215       g_variant_get (parameters, "(su)", &entry_id, &timestamp, NULL);
00216 
00217       panel_service_secondary_activate_entry (service, entry_id, timestamp);
00218 
00219       g_dbus_method_invocation_return_value (invocation, NULL);
00220       g_free (entry_id);
00221     }
00222   else if (g_strcmp0 (method_name, "ScrollEntry") == 0)
00223     {
00224       gchar *entry_id;
00225       gint32 delta;
00226       g_variant_get (parameters, "(si)", &entry_id, &delta, NULL);
00227       panel_service_scroll_entry (service, entry_id, delta);
00228       g_dbus_method_invocation_return_value (invocation, NULL);
00229       g_free(entry_id);
00230     }
00231 }
00232 
00233 static void
00234 on_service_resync (PanelService *service, const gchar *indicator_id, GDBusConnection *connection)
00235 {
00236   GError *error = NULL;
00237   g_dbus_connection_emit_signal (connection,
00238                                  S_NAME,
00239                                  S_PATH,
00240                                  S_IFACE,
00241                                  "ReSync",
00242                                  g_variant_new ("(s)", indicator_id),
00243                                  &error);
00244   if (error)
00245     {
00246       g_warning ("Unable to emit ReSync signal: %s", error->message);
00247       g_error_free (error);
00248     }
00249 }
00250 
00251 static void
00252 on_service_entry_activated (PanelService    *service,
00253                             const gchar     *entry_id,
00254                             gint x, gint y, guint w, guint h,
00255                             GDBusConnection *connection)
00256 {
00257   GError *error = NULL;
00258   g_dbus_connection_emit_signal (connection,
00259                                  S_NAME,
00260                                  S_PATH,
00261                                  S_IFACE,
00262                                  "EntryActivated",
00263                                  g_variant_new ("(s(iiuu))", entry_id, x, y, w, h),
00264                                  &error);
00265 
00266   if (error)
00267     {
00268       g_warning ("Unable to emit EntryActivated signal: %s", error->message);
00269       g_error_free (error);
00270     }
00271 }
00272 
00273 static void
00274 on_service_entry_activate_request (PanelService    *service,
00275                                    const gchar     *entry_id,
00276                                    GDBusConnection *connection)
00277 {
00278   GError *error = NULL;
00279   g_warning ("%s, entry_id:%s", G_STRFUNC, entry_id);
00280   g_dbus_connection_emit_signal (connection,
00281                                  S_NAME,
00282                                  S_PATH,
00283                                  S_IFACE,
00284                                  "EntryActivateRequest",
00285                                  g_variant_new ("(s)", entry_id),
00286                                  &error);
00287 
00288   if (error)
00289     {
00290       g_warning ("Unable to emit EntryActivateRequest signal: %s", error->message);
00291       g_error_free (error);
00292     }
00293 }
00294 
00295 static void
00296 on_service_entry_show_now_changed (PanelService    *service,
00297                                    const gchar     *entry_id,
00298                                    gboolean         show_now_state,
00299                                    GDBusConnection *connection)
00300 {
00301   GError *error = NULL;
00302   g_dbus_connection_emit_signal (connection,
00303                                  S_NAME,
00304                                  S_PATH,
00305                                  S_IFACE,
00306                                  "EntryShowNowChanged",
00307                                  g_variant_new ("(sb)", entry_id, show_now_state),
00308                                  &error);
00309 
00310   if (error)
00311     {
00312       g_warning ("Unable to emit EntryShowNowChanged signal: %s", error->message);
00313       g_error_free (error);
00314     }
00315 }
00316 
00317 static void
00318 on_bus_acquired (GDBusConnection *connection,
00319                  const gchar     *name,
00320                  gpointer         user_data)
00321 {
00322   PanelService *service = PANEL_SERVICE (user_data);
00323   guint         reg_id;
00324 
00325   reg_id = g_dbus_connection_register_object (connection,
00326                                               S_PATH,
00327                                               introspection_data->interfaces[0],
00328                                               &interface_vtable,
00329                                               service,
00330                                               NULL,
00331                                               NULL);
00332   g_signal_connect (service, "re-sync",
00333                     G_CALLBACK (on_service_resync), connection);
00334   g_signal_connect (service, "entry-activated",
00335                     G_CALLBACK (on_service_entry_activated), connection);
00336   g_signal_connect (service, "entry-activate-request",
00337                     G_CALLBACK (on_service_entry_activate_request), connection);
00338   g_signal_connect (service, "entry-show-now-changed",
00339                     G_CALLBACK (on_service_entry_show_now_changed), connection);
00340 
00341   g_debug ("%s", G_STRFUNC);
00342   g_assert (reg_id > 0);
00343 }
00344 
00345 static void
00346 on_name_acquired (GDBusConnection *connection,
00347                   const gchar     *name,
00348                   gpointer         user_data)
00349 {
00350   g_debug ("Name Acquired");
00351 }
00352 
00353 static void
00354 on_name_lost (GDBusConnection *connection,
00355               const gchar     *name,
00356               gpointer         user_data)
00357 {
00358   PanelService *service = PANEL_SERVICE (user_data);
00359               
00360   g_debug ("%s", G_STRFUNC);
00361   if (service != NULL)
00362   {
00363     g_signal_handlers_disconnect_by_func (service, on_service_resync, connection);
00364     g_signal_handlers_disconnect_by_func (service, on_service_entry_activated, connection);
00365     g_signal_handlers_disconnect_by_func (service, on_service_entry_activate_request, connection);
00366     g_signal_handlers_disconnect_by_func (service, on_service_entry_show_now_changed, connection);
00367   }
00368   gtk_main_quit ();
00369 }
00370 
00371 static void
00372 on_indicators_cleared (PanelService *service)
00373 {
00374   gtk_main_quit ();
00375 }
00376 
00377 static void
00378 on_signal (int sig)
00379 {
00380   PanelService *service = panel_service_get_default ();
00381   panel_service_clear_indicators (service);
00382   g_signal_connect (service, "indicators-cleared",
00383                     G_CALLBACK (on_indicators_cleared), NULL);
00384 }
00385 
00386 static void
00387 discard_log_message (const gchar *log_domain, GLogLevelFlags log_level,
00388                      const gchar *message, gpointer user_data)
00389 {
00390   return;
00391 }
00392 
00393 gint
00394 main (gint argc, gchar **argv)
00395 {
00396   PanelService *service;
00397   guint         owner_id;
00398 
00399   g_unsetenv("UBUNTU_MENUPROXY");
00400   g_setenv ("NO_AT_BRIDGE", "1", TRUE);
00401   g_unsetenv ("NO_GAIL");
00402 
00403   gtk_init (&argc, &argv);
00404   gtk_icon_theme_append_search_path (gtk_icon_theme_get_default(),
00405                                  INDICATORICONDIR);
00406 
00407   if (g_getenv ("SILENT_PANEL_SERVICE") != NULL)
00408   {
00409     g_log_set_default_handler (discard_log_message, NULL);
00410   }
00411 
00412   introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
00413   g_assert (introspection_data != NULL);
00414 
00415   panel_a11y_init ();
00416 
00417   service = panel_service_get_default ();
00418 
00419   owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
00420                              S_NAME,
00421                              G_BUS_NAME_OWNER_FLAGS_NONE,
00422                              on_bus_acquired,
00423                              on_name_acquired,
00424                              on_name_lost,
00425                              service,
00426                              NULL);
00427 
00428   signal (SIGINT, on_signal);
00429   signal (SIGTERM, on_signal);
00430 
00431   gtk_main ();
00432 
00433   g_bus_unown_name (owner_id);
00434   g_dbus_node_info_unref (introspection_data);
00435   g_object_unref (service);
00436 
00437   return 0;
00438 }