Back to index

libindicate  12.10.0
listener.c
Go to the documentation of this file.
00001 /*
00002 A library to allow applictions to provide simple indications of
00003 information to be displayed to users of the application through the
00004 interface shell.
00005 
00006 Copyright 2009 Canonical Ltd.
00007 
00008 Authors:
00009     Ted Gould <ted@canonical.com>
00010 
00011 This program is free software: you can redistribute it and/or modify it 
00012 under the terms of either or both of the following licenses:
00013 
00014 1) the GNU Lesser General Public License version 3, as published by the 
00015 Free Software Foundation; and/or
00016 2) the GNU Lesser General Public License version 2.1, as published by 
00017 the Free Software Foundation.
00018 
00019 This program is distributed in the hope that it will be useful, but 
00020 WITHOUT ANY WARRANTY; without even the implied warranties of 
00021 MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 
00022 PURPOSE.  See the applicable version of the GNU Lesser General Public 
00023 License for more details.
00024 
00025 You should have received a copy of both the GNU Lesser General Public 
00026 License version 3 and version 2.1 along with this program.  If not, see 
00027 <http://www.gnu.org/licenses/>
00028 */
00029 
00030 #include "listener.h"
00031 #include <dbus/dbus-glib-bindings.h>
00032 
00033 #include "../libindicate/listener-private.h"
00034 
00035 typedef enum _get_property_type get_property_type;
00036 enum _get_property_type {
00037        PROPERTY_TYPE_ICON
00038 };
00039 
00040 typedef struct _get_property_t get_property_t;
00041 struct _get_property_t {
00042        GCallback cb;
00043        gpointer data;
00044        IndicateListener * listener;
00045        IndicateListenerServer * server;
00046        IndicateListenerIndicator * indicator;
00047        gchar * property;
00048        get_property_type type;
00049 };
00050 
00051 static void
00052 get_property_cb (GObject * object, GAsyncResult * res, gpointer user_data)
00053 {
00054        get_property_t * get_property_data = (get_property_t *)user_data;
00055        GError * error = NULL;
00056        GVariant * retvalue = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error);
00057 
00058        if (error != NULL) {
00059               g_warning("Unable to get property data: %s", error->message);
00060               g_error_free(error);
00061               return;
00062        }
00063 
00064        GVariant * value = g_variant_get_child_value(retvalue, 0);
00065 
00066        switch (get_property_data->type) {
00067        case PROPERTY_TYPE_ICON: {
00068               indicate_gtk_listener_get_property_icon_cb cb = (indicate_gtk_listener_get_property_icon_cb)get_property_data->cb;
00069               const gchar * OUT_value = g_variant_get_string(value, NULL);
00070 
00071               /* There is no icon */
00072               if (OUT_value == NULL || OUT_value[0] == '\0') {
00073                      break;
00074               }
00075 
00076               gsize length = 0;
00077               guchar * icondata = g_base64_decode(OUT_value, &length);
00078               
00079               GInputStream * input = g_memory_input_stream_new_from_data(icondata, length, NULL);
00080               if (input == NULL) {
00081                      g_warning("Cound not create input stream from icon property data");
00082                      g_free(icondata);
00083                      break;
00084               }
00085 
00086               GError * error = NULL;
00087               GdkPixbuf * icon = gdk_pixbuf_new_from_stream(input, NULL, &error);
00088               if (icon != NULL) {
00089                      cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, icon, get_property_data->data);
00090               }
00091 
00092               if (error != NULL) {
00093                      g_warning("Unable to build Pixbuf from icon data: %s", error->message);
00094                      g_error_free(error);
00095               }
00096 
00097               error = NULL;
00098               g_input_stream_close(input, NULL, &error);
00099               if (error != NULL) {
00100                      g_warning("Unable to close input stream: %s", error->message);
00101                      g_error_free(error);
00102               }
00103               g_free(icondata);
00104               break;
00105        }
00106        }
00107 
00108        g_variant_unref(value);
00109        g_free(get_property_data->property);
00110        g_free(get_property_data);
00111 
00112        return;
00113 };
00114 
00115 /* A small function to take the common list of parameters and
00116    build a callback structure to hold them all.  Eventually we
00117    get the data and unwind this structure. */
00118 static void
00119 get_property_helper (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, GCallback callback, gpointer data, get_property_type prop_type)
00120 {
00121        /* g_debug("get_property_helper: %s %d", property, prop_type); */
00122        /* TODO: Do we need to somehow refcount the server/indicator while we're waiting on this? */
00123        get_property_t * get_property_data = g_new0(get_property_t, 1);
00124        get_property_data->cb = callback;
00125        get_property_data->data = data;
00126        get_property_data->listener = listener;
00127        get_property_data->server = server;
00128        get_property_data->indicator = indicator;
00129        get_property_data->property = g_strdup(property);
00130        get_property_data->type = prop_type;
00131        
00132        g_dbus_proxy_call(server->proxy,
00133                          "GetIndicatorProperty",
00134                          g_variant_new("(us)",
00135                                        INDICATE_LISTENER_INDICATOR_ID(indicator), property),
00136                          G_DBUS_CALL_FLAGS_NONE,
00137                          -1, /* timeout */
00138                          NULL, /* cancel */
00139                          get_property_cb,
00140                          get_property_data);
00141 
00142        return;
00143 }
00144 
00162 void
00163 indicate_gtk_listener_get_property_icon (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, indicate_gtk_listener_get_property_icon_cb callback, gpointer data)
00164 {
00165        return get_property_helper(listener, server, indicator, property, G_CALLBACK(callback), data, PROPERTY_TYPE_ICON);
00166 }
00167