Bugfixes and uprev of configure.in, release at-spi-1.7.11.
[platform/core/uifw/at-spi2-atk.git] / libspi / streamablecontent.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) *
4  * Copyright 2001, 2002 Sun Microsystems Inc.,
5  * Copyright 2001, 2002 Ximian, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* streamablecontent.c : implements the StreamableContent interface */
24
25 #include <config.h>
26 #include <stdio.h>
27 #include <libspi/accessible.h>
28 #include <libspi/component.h>
29 #include <libspi/streamablecontent.h>
30
31 /* Our parent Gtk object type */
32 #define PARENT_TYPE SPI_TYPE_BASE
33
34 /* A pointer to our parent object class */
35 static GObjectClass *spi_streamable_parent_class;
36
37 #define SPI_CONTENT_STREAM_TYPE            (spi_content_stream_get_type ())
38 #define SPI_CONTENT_STREAM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_CONTENT_STREAM_TYPE, SpiContentStream))
39 #define SPI_CONTENT_STREAM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_CONTENT_STREAM_TYPE, SpiContentStreamClass))
40 #define SPI_IS_CONTENT_STREAM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_CONTENT_STREAM_TYPE))
41 #define SPI_IS_CONTENT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_CONTENT_STREAM_TYPE))
42
43 typedef struct _SpiContentStream SpiContentStream;
44 typedef struct _SpiContentStreamClass SpiContentStreamClass;
45
46 struct _SpiContentStream {
47   BonoboObject parent;
48   GIOChannel *gio;
49 };
50
51 struct _SpiContentStreamClass {
52   BonoboObjectClass parent_class;
53   POA_Accessibility_ContentStream__epv epv;
54 };
55
56 GType        spi_content_stream_get_type (void);
57
58 static SpiContentStream*
59 spi_content_stream_new (GIOChannel *gio)
60 {
61   SpiContentStream *new_stream = g_object_new (SPI_CONTENT_STREAM_TYPE, NULL);
62   new_stream->gio = gio;
63   return new_stream;
64 }
65
66 static void
67 spi_content_stream_dispose (GObject *o)
68 {
69     if (SPI_IS_CONTENT_STREAM (o))
70     {
71         SpiContentStream *stream = SPI_CONTENT_STREAM (o);
72         if (stream->gio) g_io_channel_unref (stream->gio);
73     }
74 }
75
76 static CORBA_long
77 impl_content_stream_seek (PortableServer_Servant servant,
78                           const CORBA_long offset, 
79                           const Accessibility_ContentStream_SeekType whence,
80                           CORBA_Environment *ev)
81 {
82   SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
83   if (stream && stream->gio)
84   {
85       GError *err;
86       GSeekType seektype = G_SEEK_SET;
87       switch (whence) {
88           case Accessibility_ContentStream_SEEK_CURRENT:
89               seektype = G_SEEK_CUR;
90               break;
91           case Accessibility_ContentStream_SEEK_END:
92               seektype = G_SEEK_END;
93               break;
94       }
95       if (g_io_channel_seek_position (stream->gio, (gint64) offset, 
96                                      seektype, &err) == G_IO_STATUS_NORMAL)
97           return offset;
98       else
99           return -1;
100   }
101   else
102       return -1;
103 }
104
105 static CORBA_long
106 impl_content_stream_read (PortableServer_Servant servant,
107                           const CORBA_long count, 
108                           Accessibility_ContentStream_iobuf** buffer,
109                           CORBA_Environment *ev)
110 {
111   SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
112   CORBA_long realcount = 0;
113
114   if (stream && stream->gio)
115   {
116       gchar *gbuf = NULL;
117       GIOStatus status;
118       GError *err = NULL;
119  
120       /* read the giochannel and determine the actual bytes read...*/
121       if (count != -1) {
122           gbuf = g_malloc (count+1);
123           status = g_io_channel_read_chars (stream->gio, gbuf, count, &realcount, &err);
124       }
125       else
126           status = g_io_channel_read_to_end (stream->gio, &gbuf, &realcount, &err);
127
128       if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_EOF)
129       {
130           *buffer = Bonobo_Stream_iobuf__alloc ();
131           CORBA_sequence_set_release (*buffer, TRUE);
132
133           (*buffer)->_buffer = CORBA_sequence_CORBA_octet_allocbuf (realcount);
134           (*buffer)->_length = realcount;
135       
136           g_memmove ((*buffer)->_buffer, gbuf, realcount);  
137       }
138
139       g_free (gbuf);
140   }
141
142   return realcount;
143 }
144
145 static void
146 impl_content_stream_close (PortableServer_Servant servant, 
147                            CORBA_Environment *ev)
148 {
149     GIOStatus status;
150     GError *err;
151     SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
152     if (stream && stream->gio) {
153         status = g_io_channel_shutdown (stream->gio, TRUE, &err);
154         g_io_channel_unref (stream->gio);
155     }
156     if (err) g_free (err);
157 }
158
159 static void
160 spi_content_stream_class_init (SpiContentStreamClass *klass)
161 {
162   POA_Accessibility_ContentStream__epv *epv = &klass->epv;
163   GObjectClass * object_class = (GObjectClass *) klass;
164
165   epv->seek = impl_content_stream_seek;
166   epv->read = impl_content_stream_read;
167   epv->close = impl_content_stream_close;
168
169   object_class->dispose = spi_content_stream_dispose;
170 }
171
172
173 static void
174 spi_content_stream_init (SpiContentStream *stream)
175 {
176 }
177
178
179 BONOBO_TYPE_FUNC_FULL (SpiContentStream,
180                        Accessibility_ContentStream,
181                        BONOBO_TYPE_OBJECT,
182                        spi_content_stream)
183
184 static AtkStreamableContent *
185 get_streamable_from_servant (PortableServer_Servant servant)
186 {
187   SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
188   g_return_val_if_fail (object != NULL, NULL);
189   g_return_val_if_fail (ATK_IS_STREAMABLE_CONTENT(object->gobj), NULL);
190   return ATK_STREAMABLE_CONTENT (object->gobj);
191 }
192
193 /*
194  * CORBA Accessibility::StreamableContent::getContentTypes method implementation
195  */
196 static Accessibility_StringSeq*
197 impl_accessibility_streamable_get_content_types (PortableServer_Servant servant,
198                                                  CORBA_Environment     *ev)
199 {
200   Accessibility_StringSeq *typelist = Accessibility_StringSeq__alloc ();
201   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
202   int n_types, i;
203
204   typelist->_length = typelist->_maximum = 0;
205
206   g_return_val_if_fail (streamable != NULL, typelist);
207
208   n_types = atk_streamable_content_get_n_mime_types (streamable);
209
210   if (n_types)
211   {
212       typelist->_length = typelist->_maximum = n_types;
213       typelist->_buffer = Accessibility_StringSeq_allocbuf (n_types);
214       for (i = 0; i < n_types; ++i) {
215           const gchar *mimetype = atk_streamable_content_get_mime_type (streamable, i);
216           typelist->_buffer[i] = CORBA_string_dup (mimetype ? mimetype : "");
217       }
218   }
219   return typelist;
220 }
221
222 /*
223  * CORBA Accessibility::StreamableContent::getContent method implementation
224  */
225 static Bonobo_Stream
226 impl_accessibility_streamable_get_content (PortableServer_Servant servant,
227                                            const CORBA_char * content_type,
228                                            CORBA_Environment     *ev)
229 {
230   Bonobo_Stream stream;
231   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
232   GIOChannel *gio;
233
234   g_return_val_if_fail (streamable != NULL, NULL);
235
236   gio = atk_streamable_content_get_stream (streamable, content_type);
237
238   stream = CORBA_OBJECT_NIL; /* deprecated, 
239                               * and it was never implemented,
240                               * so don't bother fixing this 
241                               */
242   return stream;
243 }
244
245 /*
246  * CORBA Accessibility::StreamableContent::getStream method implementation
247  */
248 static Accessibility_ContentStream
249 impl_accessibility_streamable_get_stream (PortableServer_Servant servant,
250                                            const CORBA_char * content_type,
251                                            CORBA_Environment     *ev)
252 {
253   SpiContentStream *stream;
254   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
255   GIOChannel *gio;
256
257   g_return_val_if_fail (streamable != NULL, NULL);
258
259   gio = atk_streamable_content_get_stream (streamable, content_type);
260
261   stream = spi_content_stream_new (gio); 
262
263   return bonobo_object_dup_ref (BONOBO_OBJREF (stream), ev);
264 }
265
266 /*
267  * CORBA Accessibility::StreamableContent::getURI method implementation
268  */
269 static CORBA_string
270 impl_accessibility_streamable_get_uri (PortableServer_Servant servant,
271                                            const CORBA_char * content_type,
272                                            CORBA_Environment     *ev)
273 {
274   gchar *uri;
275   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
276
277   g_return_val_if_fail (streamable != NULL, NULL);
278
279   uri = atk_streamable_content_get_uri (streamable, content_type);
280
281   return (uri != NULL ? CORBA_string_dup (uri) : CORBA_string_dup (""));
282 }
283
284 static void
285 spi_streamable_class_init (SpiStreamableClass *klass)
286 {
287         POA_Accessibility_StreamableContent__epv *epv = &klass->epv;
288         spi_streamable_parent_class = g_type_class_peek_parent (klass);
289
290         epv->getContentTypes = impl_accessibility_streamable_get_content_types;
291         epv->getContent = impl_accessibility_streamable_get_content;
292         epv->getStream = impl_accessibility_streamable_get_stream;
293         epv->getURI = impl_accessibility_streamable_get_uri;
294 }
295
296 static void
297 spi_streamable_init (SpiStreamable *streamable)
298 {
299 }
300
301
302 SpiStreamable *
303 spi_streamable_interface_new (AtkObject *o)
304 {
305     SpiStreamable *retval = g_object_new (SPI_STREAMABLE_TYPE, NULL);
306
307     spi_base_construct (SPI_BASE (retval), G_OBJECT(o));
308
309     return retval;
310 }
311
312 BONOBO_TYPE_FUNC_FULL (SpiStreamable,
313                        Accessibility_StreamableContent,
314                        PARENT_TYPE,
315                        spi_streamable)