From 875c0e1fcd9360344e69b0a1f0276c4934904f3d Mon Sep 17 00:00:00 2001 From: Jason Conti Date: Tue, 10 May 2011 14:10:56 -0400 Subject: Renamed the rest of the files, and updated the file headers. --- src/dbus-shared.h | 3 + src/example-service.c | 126 -------------- src/indicator-example.c | 381 ------------------------------------------ src/indicator-notifications.c | 379 +++++++++++++++++++++++++++++++++++++++++ src/notifications-service.c | 124 ++++++++++++++ src/settings-shared.h | 6 +- 6 files changed, 508 insertions(+), 511 deletions(-) delete mode 100644 src/example-service.c delete mode 100644 src/indicator-example.c create mode 100644 src/indicator-notifications.c create mode 100644 src/notifications-service.c (limited to 'src') diff --git a/src/dbus-shared.h b/src/dbus-shared.h index 0b97483..e5e750b 100644 --- a/src/dbus-shared.h +++ b/src/dbus-shared.h @@ -1,6 +1,9 @@ /* An indicator to display recent notifications. +Adapted from: indicator-datetime/src/dbus-shared.c by + Ted Gould + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. diff --git a/src/example-service.c b/src/example-service.c deleted file mode 100644 index 1b197af..0000000 --- a/src/example-service.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -An example indicator. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "dbus-shared.h" -#include "settings-shared.h" - -static IndicatorService *service = NULL; -static GMainLoop *mainloop = NULL; -static DbusmenuServer *server = NULL; -static DbusmenuMenuitem *root = NULL; - -/* Global Items */ -static DbusmenuMenuitem *item_1 = NULL; -static DbusmenuMenuitem *item_2 = NULL; - -/* Test the item activation signal */ -static void -activate_cb(DbusmenuMenuitem *item, guint timestamp, const gchar *command) -{ - GError *error = NULL; - - if(!g_spawn_command_line_async(command, &error)) { - g_warning("Unable to start command %s: %s\n", command, error->message); - g_error_free(error); - } -} - -static void -build_menus(DbusmenuMenuitem *root) -{ - g_debug("Building Menus."); - if (item_1 == NULL) { - item_1 = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(item_1, DBUSMENU_MENUITEM_PROP_LABEL, _("Launch Gedit")); - dbusmenu_menuitem_child_append(root, item_1); - - g_signal_connect(G_OBJECT(item_1), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), - "gedit"); - } - if (item_2 == NULL) { - item_2 = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(item_2, DBUSMENU_MENUITEM_PROP_LABEL, _("Launch Xterm")); - dbusmenu_menuitem_child_append(root, item_2); - - g_signal_connect(G_OBJECT(item_2), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), - "xterm"); - } - - return; -} - -/* Responds to the service object saying it's time to shutdown. - It stops the mainloop. */ -static void -service_shutdown(IndicatorService *service, gpointer user_data) -{ - g_warning("Shutting down service!"); - g_main_loop_quit(mainloop); - return; -} - -/* Function to build everything up. Entry point from asm. */ -int -main(int argc, char **argv) -{ - g_type_init(); - - /* Acknowledging the service init and setting up the interface */ - service = indicator_service_new_version(SERVICE_NAME, SERVICE_VERSION); - g_signal_connect(service, INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); - - /* Setting up i18n and gettext. Apparently, we need - all of these. */ - setlocale(LC_ALL, ""); - bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain(GETTEXT_PACKAGE); - - /* Building the base menu */ - server = dbusmenu_server_new(MENU_OBJ); - root = dbusmenu_menuitem_new(); - dbusmenu_server_set_root(server, root); - - build_menus(root); - - mainloop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(mainloop); - - g_object_unref(G_OBJECT(dbus)); - g_object_unref(G_OBJECT(service)); - g_object_unref(G_OBJECT(server)); - g_object_unref(G_OBJECT(root)); - - return 0; -} diff --git a/src/indicator-example.c b/src/indicator-example.c deleted file mode 100644 index 67e7ba2..0000000 --- a/src/indicator-example.c +++ /dev/null @@ -1,381 +0,0 @@ -/* -An example indicator. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include - -/* GStuff */ -#include -#include -#include -#include -#include - -/* Indicator Stuff */ -#include -#include -#include - -/* DBusMenu */ -#include -#include -#include - -#include "dbus-shared.h" -#include "settings-shared.h" - -#define INDICATOR_EXAMPLE_TYPE (indicator_example_get_type ()) -#define INDICATOR_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_EXAMPLE_TYPE, IndicatorExample)) -#define INDICATOR_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_EXAMPLE_TYPE, IndicatorExampleClass)) -#define IS_INDICATOR_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_EXAMPLE_TYPE)) -#define IS_INDICATOR_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_EXAMPLE_TYPE)) -#define INDICATOR_EXAMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_EXAMPLE_TYPE, IndicatorExampleClass)) - -typedef struct _IndicatorExample IndicatorExample; -typedef struct _IndicatorExampleClass IndicatorExampleClass; -typedef struct _IndicatorExamplePrivate IndicatorExamplePrivate; - -struct _IndicatorExampleClass { - IndicatorObjectClass parent_class; -}; - -struct _IndicatorExample { - IndicatorObject parent; - IndicatorExamplePrivate *priv; -}; - -struct _IndicatorExamplePrivate { - GtkLabel *label; - - IndicatorServiceManager *sm; - DbusmenuGtkMenu *menu; - - gint current_state; - - GCancellable *service_proxy_cancel; - GDBusProxy *service_proxy; -}; - -enum { - STATE_NORMAL, - STATE_SHOWN, - STATE_HIDDEN -}; - -#define INDICATOR_EXAMPLE_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_EXAMPLE_TYPE, IndicatorExamplePrivate)) - -GType indicator_example_get_type(void); - -static void indicator_example_class_init(IndicatorExampleClass *klass); -static void indicator_example_init(IndicatorExample *self); -static void indicator_example_dispose(GObject *object); -static void indicator_example_finalize(GObject *object); -static GtkLabel *get_label(IndicatorObject *io); -static GtkMenu *get_menu(IndicatorObject *io); -static const gchar *get_accessible_desc(IndicatorObject *io); -static void update_label(IndicatorExample *io); -static void receive_signal(GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data); -static void service_proxy_cb(GObject *object, GAsyncResult *res, gpointer user_data); - -/* Indicator Module Config */ -INDICATOR_SET_VERSION -INDICATOR_SET_TYPE(INDICATOR_EXAMPLE_TYPE) - -G_DEFINE_TYPE (IndicatorExample, indicator_example, INDICATOR_OBJECT_TYPE); - -static void -indicator_example_class_init(IndicatorExampleClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private(klass, sizeof(IndicatorExamplePrivate)); - - object_class->dispose = indicator_example_dispose; - object_class->finalize = indicator_example_finalize; - - IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS(klass); - - io_class->get_label = get_label; - io_class->get_menu = get_menu; - io_class->get_accessible_desc = get_accessible_desc; - - return; -} - -static void -menu_visible_notify_cb(GtkWidget *menu, G_GNUC_UNUSED GParamSpec *pspec, gpointer user_data) -{ - IndicatorExample *self = INDICATOR_EXAMPLE(user_data); - g_debug("notify visible signal received"); - - // we should only react if we're currently visible - gboolean visible; - g_object_get(G_OBJECT(menu), "visible", &visible, NULL); - /* - if(visible) { - self->priv->current_state = STATE_SHOWN; - } - else { - g_debug("notify visible menu hidden"); - self->priv->current_state = STATE_HIDDEN; - } - */ - update_label(self); -} - -static void -indicator_example_init(IndicatorExample *self) -{ - self->priv = INDICATOR_EXAMPLE_GET_PRIVATE(self); - - self->priv->label = NULL; - - self->priv->current_state = STATE_NORMAL; - - self->priv->service_proxy = NULL; - - self->priv->sm = NULL; - self->priv->menu = NULL; - - self->priv->sm = indicator_service_manager_new_version(SERVICE_NAME, SERVICE_VERSION); - - self->priv->menu = dbusmenu_gtkmenu_new(SERVICE_NAME, MENU_OBJ); - - g_signal_connect(self->priv->menu, "notify::visible", G_CALLBACK(menu_visible_notify_cb), self); - - /*DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(self->priv->menu);*/ - - self->priv->service_proxy_cancel = g_cancellable_new(); - - g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - SERVICE_NAME, - SERVICE_OBJ, - SERVICE_IFACE, - self->priv->service_proxy_cancel, - service_proxy_cb, - self); - - return; -} - -/* Callback from trying to create the proxy for the serivce, this - could include starting the service. Sometime it'll fail and - we'll try to start that dang service again! */ -static void -service_proxy_cb(GObject *object, GAsyncResult *res, gpointer user_data) -{ - GError *error = NULL; - - IndicatorExample *self = INDICATOR_EXAMPLE(user_data); - g_return_if_fail(self != NULL); - - GDBusProxy *proxy = g_dbus_proxy_new_for_bus_finish(res, &error); - - IndicatorExamplePrivate *priv = INDICATOR_EXAMPLE_GET_PRIVATE(self); - - if(priv->service_proxy_cancel != NULL) { - g_object_unref(priv->service_proxy_cancel); - priv->service_proxy_cancel = NULL; - } - - if(error != NULL) { - g_warning("Could not grab DBus proxy for %s: %s", SERVICE_NAME, error->message); - g_error_free(error); - return; - } - - /* Okay, we're good to grab the proxy at this point, we're - sure that it's ours. */ - priv->service_proxy = proxy; - - g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self); - - return; -} - -static void -indicator_example_dispose(GObject *object) -{ - IndicatorExample *self = INDICATOR_EXAMPLE(object); - - if(self->priv->label != NULL) { - g_object_unref(self->priv->label); - self->priv->label = NULL; - } - - if(self->priv->menu != NULL) { - g_object_unref(G_OBJECT(self->priv->menu)); - self->priv->menu = NULL; - } - - if(self->priv->sm != NULL) { - g_object_unref(G_OBJECT(self->priv->sm)); - self->priv->sm = NULL; - } - - if(self->priv->service_proxy != NULL) { - g_object_unref(self->priv->service_proxy); - self->priv->service_proxy = NULL; - } - - G_OBJECT_CLASS (indicator_example_parent_class)->dispose (object); - return; -} - -static void -indicator_example_finalize(GObject *object) -{ - /*IndicatorExample *self = INDICATOR_EXAMPLE(object);*/ - - G_OBJECT_CLASS (indicator_example_parent_class)->finalize (object); - return; -} - -/* Updates the accessible description */ -static void -update_accessible_description(IndicatorExample *io) -{ - GList *entries = indicator_object_get_entries(INDICATOR_OBJECT(io)); - IndicatorObjectEntry *entry = (IndicatorObjectEntry *)entries->data; - - entry->accessible_desc = get_accessible_desc(INDICATOR_OBJECT(io)); - - g_signal_emit(G_OBJECT(io), - INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, - 0, - entry, - TRUE); - - g_list_free(entries); - - return; -} - -/* Updates the label */ -static void -update_label(IndicatorExample *io) -{ - IndicatorExample *self = INDICATOR_EXAMPLE(io); - - if(self->priv->label == NULL) return; - - switch(self->priv->current_state) { - case STATE_HIDDEN: - gtk_label_set_text(self->priv->label, "Hidden"); - break; - case STATE_SHOWN: - gtk_label_set_text(self->priv->label, "Shown"); - break; - default: - gtk_label_set_text(self->priv->label, "Example"); - } - - update_accessible_description(io); - - return; -} - -/* Receives all signals from the service, routed to the appropriate functions */ -static void -receive_signal(GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, - GVariant *parameters, gpointer user_data) -{ - /*IndicatorExample *self = INDICATOR_EXAMPLE(user_data);*/ - - return; -} - -/* React to the style changing, which could mean an font - update. */ -static void -style_changed(GtkWidget *widget, GtkStyle *oldstyle, gpointer data) -{ - g_debug("New style for label"); - IndicatorExample *self = INDICATOR_EXAMPLE(data); - update_label(self); - return; -} - -/* Respond to changes in the screen to update the text gravity */ -static void -update_text_gravity(GtkWidget *widget, GdkScreen *previous_screen, gpointer data) -{ - IndicatorExample *self = INDICATOR_EXAMPLE(data); - if(self->priv->label == NULL) return; - - PangoLayout *layout; - PangoContext *context; - - layout = gtk_label_get_layout(GTK_LABEL(self->priv->label)); - context = pango_layout_get_context(layout); - pango_context_set_base_gravity(context, PANGO_GRAVITY_AUTO); -} - -/* Grabs the label. Creates it if it doesn't - exist already */ -static GtkLabel * -get_label(IndicatorObject *io) -{ - IndicatorExample *self = INDICATOR_EXAMPLE(io); - - /* If there's not a label, we'll build ourselves one */ - if(self->priv->label == NULL) { - self->priv->label = GTK_LABEL(gtk_label_new("Example Init")); - gtk_label_set_justify(GTK_LABEL(self->priv->label), GTK_JUSTIFY_CENTER); - g_object_ref(G_OBJECT(self->priv->label)); - g_signal_connect(G_OBJECT(self->priv->label), "style-set", G_CALLBACK(style_changed), self); - g_signal_connect(G_OBJECT(self->priv->label), "screen-changed", G_CALLBACK(update_text_gravity), self); - update_label(self); - gtk_widget_set_visible(GTK_WIDGET(self->priv->label), TRUE); - } - - return self->priv->label; -} - -static GtkMenu * -get_menu(IndicatorObject *io) -{ - IndicatorExample *self = INDICATOR_EXAMPLE(io); - - return GTK_MENU(self->priv->menu); -} - -static const gchar * -get_accessible_desc(IndicatorObject *io) -{ - IndicatorExample *self = INDICATOR_EXAMPLE(io); - const gchar *name; - - if(self->priv->label != NULL) { - name = gtk_label_get_text(self->priv->label); - return name; - } - return NULL; -} diff --git a/src/indicator-notifications.c b/src/indicator-notifications.c new file mode 100644 index 0000000..9f6f3bb --- /dev/null +++ b/src/indicator-notifications.c @@ -0,0 +1,379 @@ +/* +An indicator to display recent notifications. + +Adapted from: indicator-datetime/src/indicator-datetime.c by + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +/* GStuff */ +#include +#include +#include +#include +#include + +/* Indicator Stuff */ +#include +#include +#include + +/* DBusMenu */ +#include +#include +#include + +#include "dbus-shared.h" +#include "settings-shared.h" + +#define INDICATOR_EXAMPLE_TYPE (indicator_example_get_type ()) +#define INDICATOR_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_EXAMPLE_TYPE, IndicatorExample)) +#define INDICATOR_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_EXAMPLE_TYPE, IndicatorExampleClass)) +#define IS_INDICATOR_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_EXAMPLE_TYPE)) +#define IS_INDICATOR_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_EXAMPLE_TYPE)) +#define INDICATOR_EXAMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_EXAMPLE_TYPE, IndicatorExampleClass)) + +typedef struct _IndicatorExample IndicatorExample; +typedef struct _IndicatorExampleClass IndicatorExampleClass; +typedef struct _IndicatorExamplePrivate IndicatorExamplePrivate; + +struct _IndicatorExampleClass { + IndicatorObjectClass parent_class; +}; + +struct _IndicatorExample { + IndicatorObject parent; + IndicatorExamplePrivate *priv; +}; + +struct _IndicatorExamplePrivate { + GtkLabel *label; + + IndicatorServiceManager *sm; + DbusmenuGtkMenu *menu; + + gint current_state; + + GCancellable *service_proxy_cancel; + GDBusProxy *service_proxy; +}; + +enum { + STATE_NORMAL, + STATE_SHOWN, + STATE_HIDDEN +}; + +#define INDICATOR_EXAMPLE_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_EXAMPLE_TYPE, IndicatorExamplePrivate)) + +GType indicator_example_get_type(void); + +static void indicator_example_class_init(IndicatorExampleClass *klass); +static void indicator_example_init(IndicatorExample *self); +static void indicator_example_dispose(GObject *object); +static void indicator_example_finalize(GObject *object); +static GtkLabel *get_label(IndicatorObject *io); +static GtkMenu *get_menu(IndicatorObject *io); +static const gchar *get_accessible_desc(IndicatorObject *io); +static void update_label(IndicatorExample *io); +static void receive_signal(GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data); +static void service_proxy_cb(GObject *object, GAsyncResult *res, gpointer user_data); + +/* Indicator Module Config */ +INDICATOR_SET_VERSION +INDICATOR_SET_TYPE(INDICATOR_EXAMPLE_TYPE) + +G_DEFINE_TYPE (IndicatorExample, indicator_example, INDICATOR_OBJECT_TYPE); + +static void +indicator_example_class_init(IndicatorExampleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private(klass, sizeof(IndicatorExamplePrivate)); + + object_class->dispose = indicator_example_dispose; + object_class->finalize = indicator_example_finalize; + + IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS(klass); + + io_class->get_label = get_label; + io_class->get_menu = get_menu; + io_class->get_accessible_desc = get_accessible_desc; + + return; +} + +static void +menu_visible_notify_cb(GtkWidget *menu, G_GNUC_UNUSED GParamSpec *pspec, gpointer user_data) +{ + IndicatorExample *self = INDICATOR_EXAMPLE(user_data); + g_debug("notify visible signal received"); + + // we should only react if we're currently visible + gboolean visible; + g_object_get(G_OBJECT(menu), "visible", &visible, NULL); + /* + if(visible) { + self->priv->current_state = STATE_SHOWN; + } + else { + g_debug("notify visible menu hidden"); + self->priv->current_state = STATE_HIDDEN; + } + */ + update_label(self); +} + +static void +indicator_example_init(IndicatorExample *self) +{ + self->priv = INDICATOR_EXAMPLE_GET_PRIVATE(self); + + self->priv->label = NULL; + + self->priv->current_state = STATE_NORMAL; + + self->priv->service_proxy = NULL; + + self->priv->sm = NULL; + self->priv->menu = NULL; + + self->priv->sm = indicator_service_manager_new_version(SERVICE_NAME, SERVICE_VERSION); + + self->priv->menu = dbusmenu_gtkmenu_new(SERVICE_NAME, MENU_OBJ); + + g_signal_connect(self->priv->menu, "notify::visible", G_CALLBACK(menu_visible_notify_cb), self); + + /*DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(self->priv->menu);*/ + + self->priv->service_proxy_cancel = g_cancellable_new(); + + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + SERVICE_NAME, + SERVICE_OBJ, + SERVICE_IFACE, + self->priv->service_proxy_cancel, + service_proxy_cb, + self); + + return; +} + +/* Callback from trying to create the proxy for the serivce, this + could include starting the service. Sometime it'll fail and + we'll try to start that dang service again! */ +static void +service_proxy_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + + IndicatorExample *self = INDICATOR_EXAMPLE(user_data); + g_return_if_fail(self != NULL); + + GDBusProxy *proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + + IndicatorExamplePrivate *priv = INDICATOR_EXAMPLE_GET_PRIVATE(self); + + if(priv->service_proxy_cancel != NULL) { + g_object_unref(priv->service_proxy_cancel); + priv->service_proxy_cancel = NULL; + } + + if(error != NULL) { + g_warning("Could not grab DBus proxy for %s: %s", SERVICE_NAME, error->message); + g_error_free(error); + return; + } + + /* Okay, we're good to grab the proxy at this point, we're + sure that it's ours. */ + priv->service_proxy = proxy; + + g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self); + + return; +} + +static void +indicator_example_dispose(GObject *object) +{ + IndicatorExample *self = INDICATOR_EXAMPLE(object); + + if(self->priv->label != NULL) { + g_object_unref(self->priv->label); + self->priv->label = NULL; + } + + if(self->priv->menu != NULL) { + g_object_unref(G_OBJECT(self->priv->menu)); + self->priv->menu = NULL; + } + + if(self->priv->sm != NULL) { + g_object_unref(G_OBJECT(self->priv->sm)); + self->priv->sm = NULL; + } + + if(self->priv->service_proxy != NULL) { + g_object_unref(self->priv->service_proxy); + self->priv->service_proxy = NULL; + } + + G_OBJECT_CLASS (indicator_example_parent_class)->dispose (object); + return; +} + +static void +indicator_example_finalize(GObject *object) +{ + /*IndicatorExample *self = INDICATOR_EXAMPLE(object);*/ + + G_OBJECT_CLASS (indicator_example_parent_class)->finalize (object); + return; +} + +/* Updates the accessible description */ +static void +update_accessible_description(IndicatorExample *io) +{ + GList *entries = indicator_object_get_entries(INDICATOR_OBJECT(io)); + IndicatorObjectEntry *entry = (IndicatorObjectEntry *)entries->data; + + entry->accessible_desc = get_accessible_desc(INDICATOR_OBJECT(io)); + + g_signal_emit(G_OBJECT(io), + INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, + 0, + entry, + TRUE); + + g_list_free(entries); + + return; +} + +/* Updates the label */ +static void +update_label(IndicatorExample *io) +{ + IndicatorExample *self = INDICATOR_EXAMPLE(io); + + if(self->priv->label == NULL) return; + + switch(self->priv->current_state) { + case STATE_HIDDEN: + gtk_label_set_text(self->priv->label, "Hidden"); + break; + case STATE_SHOWN: + gtk_label_set_text(self->priv->label, "Shown"); + break; + default: + gtk_label_set_text(self->priv->label, "Example"); + } + + update_accessible_description(io); + + return; +} + +/* Receives all signals from the service, routed to the appropriate functions */ +static void +receive_signal(GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, + GVariant *parameters, gpointer user_data) +{ + /*IndicatorExample *self = INDICATOR_EXAMPLE(user_data);*/ + + return; +} + +/* React to the style changing, which could mean an font + update. */ +static void +style_changed(GtkWidget *widget, GtkStyle *oldstyle, gpointer data) +{ + g_debug("New style for label"); + IndicatorExample *self = INDICATOR_EXAMPLE(data); + update_label(self); + return; +} + +/* Respond to changes in the screen to update the text gravity */ +static void +update_text_gravity(GtkWidget *widget, GdkScreen *previous_screen, gpointer data) +{ + IndicatorExample *self = INDICATOR_EXAMPLE(data); + if(self->priv->label == NULL) return; + + PangoLayout *layout; + PangoContext *context; + + layout = gtk_label_get_layout(GTK_LABEL(self->priv->label)); + context = pango_layout_get_context(layout); + pango_context_set_base_gravity(context, PANGO_GRAVITY_AUTO); +} + +/* Grabs the label. Creates it if it doesn't + exist already */ +static GtkLabel * +get_label(IndicatorObject *io) +{ + IndicatorExample *self = INDICATOR_EXAMPLE(io); + + /* If there's not a label, we'll build ourselves one */ + if(self->priv->label == NULL) { + self->priv->label = GTK_LABEL(gtk_label_new("Example Init")); + gtk_label_set_justify(GTK_LABEL(self->priv->label), GTK_JUSTIFY_CENTER); + g_object_ref(G_OBJECT(self->priv->label)); + g_signal_connect(G_OBJECT(self->priv->label), "style-set", G_CALLBACK(style_changed), self); + g_signal_connect(G_OBJECT(self->priv->label), "screen-changed", G_CALLBACK(update_text_gravity), self); + update_label(self); + gtk_widget_set_visible(GTK_WIDGET(self->priv->label), TRUE); + } + + return self->priv->label; +} + +static GtkMenu * +get_menu(IndicatorObject *io) +{ + IndicatorExample *self = INDICATOR_EXAMPLE(io); + + return GTK_MENU(self->priv->menu); +} + +static const gchar * +get_accessible_desc(IndicatorObject *io) +{ + IndicatorExample *self = INDICATOR_EXAMPLE(io); + const gchar *name; + + if(self->priv->label != NULL) { + name = gtk_label_get_text(self->priv->label); + return name; + } + return NULL; +} diff --git a/src/notifications-service.c b/src/notifications-service.c new file mode 100644 index 0000000..219a7ff --- /dev/null +++ b/src/notifications-service.c @@ -0,0 +1,124 @@ +/* +An indicator to display recent notifications. + +Adapted from: indicator-datetime/src/datetime-service.c by + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "dbus-shared.h" +#include "settings-shared.h" + +static IndicatorService *service = NULL; +static GMainLoop *mainloop = NULL; +static DbusmenuServer *server = NULL; +static DbusmenuMenuitem *root = NULL; + +/* Global Items */ +static DbusmenuMenuitem *item_1 = NULL; +static DbusmenuMenuitem *item_2 = NULL; + +/* Test the item activation signal */ +static void +activate_cb(DbusmenuMenuitem *item, guint timestamp, const gchar *command) +{ + GError *error = NULL; + + if(!g_spawn_command_line_async(command, &error)) { + g_warning("Unable to start command %s: %s\n", command, error->message); + g_error_free(error); + } +} + +static void +build_menus(DbusmenuMenuitem *root) +{ + g_debug("Building Menus."); + if (item_1 == NULL) { + item_1 = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(item_1, DBUSMENU_MENUITEM_PROP_LABEL, _("Launch Gedit")); + dbusmenu_menuitem_child_append(root, item_1); + + g_signal_connect(G_OBJECT(item_1), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), + "gedit"); + } + if (item_2 == NULL) { + item_2 = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(item_2, DBUSMENU_MENUITEM_PROP_LABEL, _("Launch Xterm")); + dbusmenu_menuitem_child_append(root, item_2); + + g_signal_connect(G_OBJECT(item_2), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), + "xterm"); + } + + return; +} + +/* Responds to the service object saying it's time to shutdown. + It stops the mainloop. */ +static void +service_shutdown(IndicatorService *service, gpointer user_data) +{ + g_warning("Shutting down service!"); + g_main_loop_quit(mainloop); + return; +} + +/* Function to build everything up. Entry point from asm. */ +int +main(int argc, char **argv) +{ + g_type_init(); + + /* Acknowledging the service init and setting up the interface */ + service = indicator_service_new_version(SERVICE_NAME, SERVICE_VERSION); + g_signal_connect(service, INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); + + /* Setting up i18n and gettext. Apparently, we need + all of these. */ + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain(GETTEXT_PACKAGE); + + /* Building the base menu */ + server = dbusmenu_server_new(MENU_OBJ); + root = dbusmenu_menuitem_new(); + dbusmenu_server_set_root(server, root); + + build_menus(root); + + mainloop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(mainloop); + + g_object_unref(G_OBJECT(dbus)); + g_object_unref(G_OBJECT(service)); + g_object_unref(G_OBJECT(server)); + g_object_unref(G_OBJECT(root)); + + return 0; +} diff --git a/src/settings-shared.h b/src/settings-shared.h index 7e74883..0634a02 100644 --- a/src/settings-shared.h +++ b/src/settings-shared.h @@ -1,9 +1,7 @@ /* -An example indicator. +An indicator to display recent notifications. -Copyright 2010 Canonical Ltd. - -Authors: +Adapted from: indicator-datetime/src/settings-shared.c by Ted Gould This program is free software: you can redistribute it and/or modify it -- cgit v1.2.3