1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 /* modest-tny-stream-gtkhtml.c */
33 #include "modest-tny-stream-gtkhtml.h"
34 #include "modest-gtkhtml-mime-part-view.h"
35 #include <tny-stream.h>
36 #include <gtkhtml/gtkhtml-stream.h>
37 #include <gtkhtml/gtkhtml-search.h>
39 /* 'private'/'protected' functions */
40 static void modest_tny_stream_gtkhtml_class_init (ModestTnyStreamGtkhtmlClass *klass);
41 static void modest_tny_stream_gtkhtml_init (ModestTnyStreamGtkhtml *obj);
42 static void modest_tny_stream_gtkhtml_finalize (GObject *obj);
44 static void modest_tny_stream_gtkhml_iface_init (gpointer g_iface, gpointer iface_data);
46 static void stop_streams (ModestGtkhtmlMimePartView *view, gpointer userdata);
55 typedef struct _ModestTnyStreamGtkhtmlPrivate ModestTnyStreamGtkhtmlPrivate;
56 struct _ModestTnyStreamGtkhtmlPrivate {
57 GtkHTMLStream *stream;
59 guint stop_streams_id;
61 #define MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
62 MODEST_TYPE_TNY_STREAM_GTKHTML, \
63 ModestTnyStreamGtkhtmlPrivate))
65 static GObjectClass *parent_class = NULL;
67 /* uncomment the following if you have defined any signals */
68 /* static guint signals[LAST_SIGNAL] = {0}; */
71 modest_tny_stream_gtkhtml_get_type (void)
73 static GType my_type = 0;
75 static const GTypeInfo my_info = {
76 sizeof(ModestTnyStreamGtkhtmlClass),
78 NULL, /* base finalize */
79 (GClassInitFunc) modest_tny_stream_gtkhtml_class_init,
80 NULL, /* class finalize */
81 NULL, /* class data */
82 sizeof(ModestTnyStreamGtkhtml),
84 (GInstanceInitFunc) modest_tny_stream_gtkhtml_init,
88 static const GInterfaceInfo iface_info = {
89 (GInterfaceInitFunc) modest_tny_stream_gtkhml_iface_init,
90 NULL, /* interface_finalize */
91 NULL /* interface_data */
94 my_type = g_type_register_static (G_TYPE_OBJECT,
95 "ModestTnyStreamGtkhtml",
98 g_type_add_interface_static (my_type, TNY_TYPE_STREAM,
106 modest_tny_stream_gtkhtml_class_init (ModestTnyStreamGtkhtmlClass *klass)
108 GObjectClass *gobject_class;
109 gobject_class = (GObjectClass*) klass;
111 parent_class = g_type_class_peek_parent (klass);
112 gobject_class->finalize = modest_tny_stream_gtkhtml_finalize;
114 g_type_class_add_private (gobject_class, sizeof(ModestTnyStreamGtkhtmlPrivate));
118 modest_tny_stream_gtkhtml_init (ModestTnyStreamGtkhtml *obj)
120 ModestTnyStreamGtkhtmlPrivate *priv;
121 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(obj);
125 priv->stop_streams_id = 0;
129 modest_tny_stream_gtkhtml_finalize (GObject *obj)
131 ModestTnyStreamGtkhtmlPrivate *priv;
133 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(obj);
136 if (priv->stop_streams_id > 0) {
137 g_signal_handler_disconnect (G_OBJECT (priv->html), priv->stop_streams_id);
138 priv->stop_streams_id = 0;
142 g_object_unref (priv->html);
148 modest_tny_stream_gtkhtml_new (GtkHTMLStream *stream, GtkHTML *html)
151 ModestTnyStreamGtkhtmlPrivate *priv;
153 obj = G_OBJECT(g_object_new(MODEST_TYPE_TNY_STREAM_GTKHTML, NULL));
154 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(obj);
156 g_return_val_if_fail (stream, NULL);
158 priv->stream = stream;
159 priv->html = g_object_ref (html);
161 priv->stop_streams_id = g_signal_connect (G_OBJECT (html), "stop-streams",
162 G_CALLBACK (stop_streams), obj);
168 /* the rest are interface functions */
172 gtkhtml_read (TnyStream *self, char *buffer, size_t n)
174 return -1; /* we cannot read */
178 ModestTnyStreamGtkhtmlPrivate *priv;
186 write_in_mainloop (gpointer userdata)
188 WriteInfo * info = (WriteInfo *) userdata;
190 g_mutex_lock (info->mutex);
191 if (info->priv->html && info->priv->stream)
192 gtk_html_stream_write (info->priv->stream, info->buffer, info->n);
193 g_cond_signal (info->cond);
194 g_mutex_unlock (info->mutex);
201 gtkhtml_write (TnyStream *self, const char *buffer, size_t n)
203 ModestTnyStreamGtkhtmlPrivate *priv;
206 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(self);
209 g_print ("modest: cannot write to closed stream\n");
213 if (n == 0 || !buffer)
216 if (!priv->html || !GTK_WIDGET_VISIBLE (priv->html))
219 info = g_slice_new (WriteInfo);
220 info->mutex = g_mutex_new ();
222 info->buffer = buffer;
224 info->cond = g_cond_new ();
226 if (g_main_context_acquire (NULL)) {
227 write_in_mainloop (info);
228 g_main_context_release (NULL);
230 g_mutex_lock (info->mutex);
231 g_idle_add (write_in_mainloop, info);
232 g_cond_wait (info->cond, info->mutex);
233 g_mutex_unlock (info->mutex);
236 g_cond_free (info->cond);
237 g_mutex_free (info->mutex);
238 g_slice_free (WriteInfo, info);
245 gtkhtml_flush (TnyStream *self)
252 ModestTnyStreamGtkhtmlPrivate *priv;
258 close_in_mainloop (gpointer userdata)
260 CloseInfo * info = (CloseInfo *) userdata;
262 g_mutex_lock (info->mutex);
263 if (info->priv->html && GTK_WIDGET_VISIBLE (info->priv->html))
264 gtk_html_stream_close (info->priv->stream, GTK_HTML_STREAM_OK);
265 g_cond_signal (info->cond);
266 g_mutex_unlock (info->mutex);
272 gtkhtml_close (TnyStream *self)
274 ModestTnyStreamGtkhtmlPrivate *priv;
275 g_return_val_if_fail (self, 0);
276 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(self);
278 if (priv->html && GTK_WIDGET_VISIBLE (priv->html)) {
281 info = g_slice_new (CloseInfo);
282 info->mutex = g_mutex_new ();
283 info->cond = g_cond_new ();
286 if (g_main_context_acquire (NULL)) {
287 close_in_mainloop (info);
288 g_main_context_release (NULL);
290 g_mutex_lock (info->mutex);
291 g_idle_add (close_in_mainloop, info);
292 g_cond_wait (info->cond, info->mutex);
293 g_mutex_unlock (info->mutex);
296 g_cond_free (info->cond);
297 g_mutex_free (info->mutex);
298 g_slice_free (CloseInfo, info);
303 if (priv->html && priv->stop_streams_id > 0) {
304 g_signal_handler_disconnect (G_OBJECT (priv->html), priv->stop_streams_id);
305 priv->stop_streams_id = 0;
308 g_object_unref (priv->html);
317 gtkhtml_is_eos (TnyStream *self)
325 gtkhtml_reset (TnyStream *self)
332 gtkhtml_write_to_stream (TnyStream *self, TnyStream *output)
338 stop_streams (ModestGtkhtmlMimePartView *view, gpointer userdata)
340 ModestTnyStreamGtkhtml *self = (ModestTnyStreamGtkhtml *) userdata;
341 ModestTnyStreamGtkhtmlPrivate *priv;
343 g_return_if_fail (self);
344 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(self);
346 if (priv->html && priv->stop_streams_id > 0) {
347 g_signal_handler_disconnect (G_OBJECT (priv->html), priv->stop_streams_id);
348 priv->stop_streams_id = 0;
352 g_object_unref (priv->html);
358 modest_tny_stream_gtkhml_iface_init (gpointer g_iface, gpointer iface_data)
360 TnyStreamIface *klass;
362 g_return_if_fail (g_iface);
364 klass = (TnyStreamIface*) g_iface;
366 klass->read = gtkhtml_read;
367 klass->write = gtkhtml_write;
368 klass->flush = gtkhtml_flush;
369 klass->close = gtkhtml_close;
370 klass->is_eos = gtkhtml_is_eos;
371 klass->reset = gtkhtml_reset;
372 klass->write_to_stream = gtkhtml_write_to_stream;