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;
64 #define MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
65 MODEST_TYPE_TNY_STREAM_GTKHTML, \
66 ModestTnyStreamGtkhtmlPrivate))
68 static GObjectClass *parent_class = NULL;
70 /* uncomment the following if you have defined any signals */
71 /* static guint signals[LAST_SIGNAL] = {0}; */
74 modest_tny_stream_gtkhtml_get_type (void)
76 static GType my_type = 0;
78 static const GTypeInfo my_info = {
79 sizeof(ModestTnyStreamGtkhtmlClass),
81 NULL, /* base finalize */
82 (GClassInitFunc) modest_tny_stream_gtkhtml_class_init,
83 NULL, /* class finalize */
84 NULL, /* class data */
85 sizeof(ModestTnyStreamGtkhtml),
87 (GInstanceInitFunc) modest_tny_stream_gtkhtml_init,
91 static const GInterfaceInfo iface_info = {
92 (GInterfaceInitFunc) modest_tny_stream_gtkhml_iface_init,
93 NULL, /* interface_finalize */
94 NULL /* interface_data */
97 my_type = g_type_register_static (G_TYPE_OBJECT,
98 "ModestTnyStreamGtkhtml",
101 g_type_add_interface_static (my_type, TNY_TYPE_STREAM,
109 modest_tny_stream_gtkhtml_class_init (ModestTnyStreamGtkhtmlClass *klass)
111 GObjectClass *gobject_class;
112 gobject_class = (GObjectClass*) klass;
114 parent_class = g_type_class_peek_parent (klass);
115 gobject_class->finalize = modest_tny_stream_gtkhtml_finalize;
117 g_type_class_add_private (gobject_class, sizeof(ModestTnyStreamGtkhtmlPrivate));
121 modest_tny_stream_gtkhtml_init (ModestTnyStreamGtkhtml *obj)
123 ModestTnyStreamGtkhtmlPrivate *priv;
124 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(obj);
128 priv->stop_streams_id = 0;
131 priv->current_size = 0;
135 modest_tny_stream_gtkhtml_finalize (GObject *obj)
137 ModestTnyStreamGtkhtmlPrivate *priv;
139 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(obj);
142 if (priv->stop_streams_id > 0) {
143 g_signal_handler_disconnect (G_OBJECT (priv->html), priv->stop_streams_id);
144 priv->stop_streams_id = 0;
148 g_object_unref (priv->html);
154 modest_tny_stream_gtkhtml_new (GtkHTMLStream *stream, GtkHTML *html)
157 ModestTnyStreamGtkhtmlPrivate *priv;
159 obj = G_OBJECT(g_object_new(MODEST_TYPE_TNY_STREAM_GTKHTML, NULL));
160 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(obj);
162 g_return_val_if_fail (stream, NULL);
164 priv->stream = stream;
165 priv->html = g_object_ref (html);
167 priv->stop_streams_id = g_signal_connect (G_OBJECT (html), "stop-streams",
168 G_CALLBACK (stop_streams), obj);
169 priv->current_size = 0;
175 /* the rest are interface functions */
179 gtkhtml_read (TnyStream *self, char *buffer, size_t n)
181 return -1; /* we cannot read */
186 gtkhtml_write (TnyStream *self, const char *buffer, size_t n)
188 ModestTnyStreamGtkhtmlPrivate *priv;
190 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(self);
193 g_print ("modest: cannot write to closed stream\n");
197 if (n == 0 || !buffer)
200 if (!priv->html || !GTK_WIDGET_VISIBLE (priv->html))
203 if (priv->max_size > 0) {
205 /* We only use the maximum size for write method, and even we
206 * ignore and fake as we would do a successfull read */
207 if (priv->current_size >= priv->max_size)
210 if (priv->current_size + n > priv->max_size)
211 n = priv->max_size - priv->current_size;
214 if (!g_main_context_is_owner (NULL))
215 gdk_threads_enter ();
217 gtk_html_stream_write (priv->stream, buffer, n);
219 if (!g_main_context_is_owner (NULL))
220 gdk_threads_leave ();
221 priv->current_size += n;
228 gtkhtml_flush (TnyStream *self)
235 gtkhtml_close (TnyStream *self)
237 ModestTnyStreamGtkhtmlPrivate *priv;
238 g_return_val_if_fail (self, 0);
239 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(self);
241 if (priv->html && GTK_WIDGET_VISIBLE (priv->html)) {
242 if (!g_main_context_is_owner (NULL))
243 gdk_threads_enter ();
245 gtk_html_stream_close (priv->stream, GTK_HTML_STREAM_OK);
247 if (!g_main_context_is_owner (NULL))
248 gdk_threads_leave ();
252 if (priv->html && priv->stop_streams_id > 0) {
253 g_signal_handler_disconnect (G_OBJECT (priv->html), priv->stop_streams_id);
254 priv->stop_streams_id = 0;
257 g_object_unref (priv->html);
266 gtkhtml_is_eos (TnyStream *self)
274 gtkhtml_reset (TnyStream *self)
281 gtkhtml_write_to_stream (TnyStream *self, TnyStream *output)
287 stop_streams (ModestGtkhtmlMimePartView *view, gpointer userdata)
289 ModestTnyStreamGtkhtml *self = (ModestTnyStreamGtkhtml *) userdata;
290 ModestTnyStreamGtkhtmlPrivate *priv;
292 g_return_if_fail (self);
293 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE(self);
295 if (priv->html && priv->stop_streams_id > 0) {
296 g_signal_handler_disconnect (G_OBJECT (priv->html), priv->stop_streams_id);
297 priv->stop_streams_id = 0;
301 g_object_unref (priv->html);
307 modest_tny_stream_gtkhtml_set_max_size (ModestTnyStreamGtkhtml *stream,
310 ModestTnyStreamGtkhtmlPrivate *priv;
312 g_return_if_fail (MODEST_IS_TNY_STREAM_GTKHTML (stream));
313 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE (stream);
315 priv->max_size = max_size;
319 modest_tny_stream_gtkhtml_get_max_size (ModestTnyStreamGtkhtml *stream)
321 ModestTnyStreamGtkhtmlPrivate *priv;
323 g_return_val_if_fail (MODEST_IS_TNY_STREAM_GTKHTML (stream), 0);
324 priv = MODEST_TNY_STREAM_GTKHTML_GET_PRIVATE (stream);
326 return priv->max_size;
330 modest_tny_stream_gtkhml_iface_init (gpointer g_iface, gpointer iface_data)
332 TnyStreamIface *klass;
334 g_return_if_fail (g_iface);
336 klass = (TnyStreamIface*) g_iface;
338 klass->read = gtkhtml_read;
339 klass->write = gtkhtml_write;
340 klass->flush = gtkhtml_flush;
341 klass->close = gtkhtml_close;
342 klass->is_eos = gtkhtml_is_eos;
343 klass->reset = gtkhtml_reset;
344 klass->write_to_stream = gtkhtml_write_to_stream;