gio/ docs/reference/gio Merged gio-standalone into glib.
[platform/upstream/glib.git] / gio / gloadableicon.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include <config.h>
24
25 #include "gsimpleasyncresult.h"
26 #include "gloadableicon.h"
27 #include "glibintl.h"
28
29 static void          g_loadable_icon_real_load_async  (GLoadableIcon        *icon,
30                                                        int                   size,
31                                                        GCancellable         *cancellable,
32                                                        GAsyncReadyCallback   callback,
33                                                        gpointer              user_data);
34 static GInputStream *g_loadable_icon_real_load_finish (GLoadableIcon        *icon,
35                                                        GAsyncResult         *res,
36                                                        char                **type,
37                                                        GError              **error);
38 static void          g_loadable_icon_base_init        (gpointer              g_class);
39 static void          g_loadable_icon_class_init       (gpointer              g_class,
40                                                        gpointer              class_data);
41
42 GType
43 g_loadable_icon_get_type (void)
44 {
45   static GType loadable_icon_type = 0;
46
47   if (! loadable_icon_type)
48     {
49       static const GTypeInfo loadable_icon_info =
50         {
51         sizeof (GLoadableIconIface), /* class_size */
52         g_loadable_icon_base_init,   /* base_init */
53         NULL,           /* base_finalize */
54         g_loadable_icon_class_init,
55         NULL,           /* class_finalize */
56         NULL,           /* class_data */
57         0,
58         0,              /* n_preallocs */
59         NULL
60       };
61
62       loadable_icon_type =
63         g_type_register_static (G_TYPE_INTERFACE, I_("GLoadableIcon"),
64                                 &loadable_icon_info, 0);
65
66       g_type_interface_add_prerequisite (loadable_icon_type, G_TYPE_ICON);
67     }
68
69   return loadable_icon_type;
70 }
71
72 static void
73 g_loadable_icon_class_init (gpointer g_class,
74                             gpointer class_data)
75 {
76   GLoadableIconIface *iface = g_class;
77
78   iface->load_async = g_loadable_icon_real_load_async;
79   iface->load_finish = g_loadable_icon_real_load_finish;
80 }
81
82 static void
83 g_loadable_icon_base_init (gpointer g_class)
84 {
85 }
86
87 /**
88  * g_loadable_icon_load:
89  * @icon:
90  * @size:
91  * @type:
92  * @cancellable: optional #GCancellable object, %NULL to ignore. 
93  * @error: a #GError location to store the error occuring, or %NULL to 
94  * ignore.
95  * Returns: 
96  **/
97 GInputStream *
98 g_loadable_icon_load (GLoadableIcon        *icon,
99                       int                   size,
100                       char                **type,
101                       GCancellable         *cancellable,
102                       GError              **error)
103 {
104   GLoadableIconIface *iface;
105
106   g_return_val_if_fail (G_IS_LOADABLE_ICON (icon), NULL);
107
108   iface = G_LOADABLE_ICON_GET_IFACE (icon);
109
110   return (* iface->load) (icon, size, type, cancellable, error);
111   
112 }
113
114 /**
115  * g_loadable_icon_load_async:
116  * @icon:
117  * @size:
118  * @cancellable: optional #GCancellable object, %NULL to ignore. @callback:
119  * @user_data:
120  * 
121  * Loads an icon asynchronously.
122  * 
123  **/
124 void
125 g_loadable_icon_load_async (GLoadableIcon        *icon,
126                             int                   size,
127                             GCancellable         *cancellable,
128                             GAsyncReadyCallback   callback,
129                             gpointer              user_data)
130 {
131   GLoadableIconIface *iface;
132   
133   g_return_if_fail (G_IS_LOADABLE_ICON (icon));
134
135   iface = G_LOADABLE_ICON_GET_IFACE (icon);
136
137   (* iface->load_async) (icon, size, cancellable, callback, user_data);
138   
139 }
140
141 /**
142  * g_loadable_icon_load_finish:
143  * @icon:
144  * @res:
145  * @type:
146  * @error: a #GError location to store the error occuring, or %NULL to 
147  * ignore.
148  * Returns:
149  **/
150 GInputStream *
151 g_loadable_icon_load_finish (GLoadableIcon        *icon,
152                              GAsyncResult         *res,
153                              char                **type,
154                              GError              **error)
155 {
156   GLoadableIconIface *iface;
157   
158   g_return_val_if_fail (G_IS_LOADABLE_ICON (icon), NULL);
159   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
160
161   if (G_IS_SIMPLE_ASYNC_RESULT (res))
162     {
163       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
164       if (g_simple_async_result_propagate_error (simple, error))
165         return NULL;
166     }
167   
168   iface = G_LOADABLE_ICON_GET_IFACE (icon);
169
170   return (* iface->load_finish) (icon, res, type, error);
171   
172 }
173
174 /********************************************
175  *   Default implementation of async load   *
176  ********************************************/
177
178 typedef struct {
179   int size;
180   char *type;
181   GInputStream *stream;
182 } LoadData;
183
184 static void
185 load_data_free (LoadData *data)
186 {
187   if (data->stream)
188     g_object_unref (data->stream);
189   g_free (data->type);
190   g_free (data);
191 }
192
193 static void
194 load_async_thread (GSimpleAsyncResult *res,
195                    GObject *object,
196                    GCancellable *cancellable)
197 {
198   GLoadableIconIface *iface;
199   GInputStream *stream;
200   LoadData *data;
201   GError *error = NULL;
202   char *type = NULL;
203
204   data = g_simple_async_result_get_op_res_gpointer (res);
205   
206   iface = G_LOADABLE_ICON_GET_IFACE (object);
207   stream = iface->load (G_LOADABLE_ICON (object), data->size, &type, cancellable, &error);
208
209   if (stream == NULL)
210     {
211       g_simple_async_result_set_from_error (res, error);
212       g_error_free (error);
213     }
214   else
215     {
216       data->stream = stream;
217       data->type = type;
218     }
219 }
220
221
222
223 static void
224 g_loadable_icon_real_load_async (GLoadableIcon        *icon,
225                                  int                   size,
226                                  GCancellable         *cancellable,
227                                  GAsyncReadyCallback   callback,
228                                  gpointer              user_data)
229 {
230   GSimpleAsyncResult *res;
231   LoadData *data;
232   
233   res = g_simple_async_result_new (G_OBJECT (icon), callback, user_data, g_loadable_icon_real_load_async);
234   data = g_new0 (LoadData, 1);
235   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify) load_data_free);
236   g_simple_async_result_run_in_thread (res, load_async_thread, 0, cancellable);
237   g_object_unref (res);
238 }
239
240 static GInputStream *
241 g_loadable_icon_real_load_finish (GLoadableIcon        *icon,
242                                   GAsyncResult         *res,
243                                   char                **type,
244                                   GError              **error)
245 {
246   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
247   LoadData *data;
248
249   g_assert (g_simple_async_result_get_source_tag (simple) == g_loadable_icon_real_load_async);
250
251   data = g_simple_async_result_get_op_res_gpointer (simple);
252
253   if (type)
254     {
255       *type = data->type;
256       data->type = NULL;
257     }
258
259   return g_object_ref (data->stream);
260 }