2 * Copyright (C) 2006 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
24 #include "swfdec_gtk_socket.h"
25 #include <libsoup/soup.h>
26 #include <libsoup/soup-address.h>
31 * SECTION:SwfdecGtkSocket
32 * @title: SwfdecGtkSocket
33 * @short_description: a socket implementation integrating into the Gtk main loop
34 * @see_also: #SwfdecSocket, #SwfdecGtkPlayer
36 * #SwfdecGtkSocket is a #SwfdecSocket that is a socket implementation that
37 * uses libsoup and integrates with the Gtk main loop. It is used by default
38 * by the #SwfecGtkPlayer.
44 * This is the object used to represent a socket. It is completely private.
47 struct _SwfdecGtkSocket
51 SoupSocket
* sock
; /* libsoup socket we're using */
54 struct _SwfdecGtkSocketClass
{
55 SwfdecSocketClass socket_class
;
58 /*** SwfdecGtkSocket ***/
60 G_DEFINE_TYPE (SwfdecGtkSocket
, swfdec_gtk_socket
, SWFDEC_TYPE_SOCKET
)
63 swfdec_gtk_socket_close (SwfdecStream
*stream
)
65 SwfdecGtkSocket
*gtk
= SWFDEC_GTK_SOCKET (stream
);
67 soup_socket_disconnect (gtk
->sock
);
71 swfdec_gtk_socket_do_disconnect (SoupSocket
*sock
, SwfdecGtkSocket
*gtk
)
73 swfdec_stream_close (SWFDEC_STREAM (gtk
));
77 swfdec_gtk_socket_do_read (SoupSocket
*sock
, SwfdecGtkSocket
*gtk
)
79 #define SWFDEC_GTK_SOCKET_BLOCK_SIZE 1024
81 SoupSocketIOStatus status
;
86 buffer
= swfdec_buffer_new (SWFDEC_GTK_SOCKET_BLOCK_SIZE
);
87 status
= soup_socket_read (sock
, buffer
->data
,
88 SWFDEC_GTK_SOCKET_BLOCK_SIZE
, &len
, NULL
, &error
);
92 swfdec_stream_push (SWFDEC_STREAM (gtk
), buffer
);
94 case SOUP_SOCKET_WOULD_BLOCK
:
96 swfdec_buffer_unref (buffer
);
98 case SOUP_SOCKET_ERROR
:
99 swfdec_buffer_unref (buffer
);
100 swfdec_stream_error (SWFDEC_STREAM (gtk
), "%s", error
->message
);
101 g_error_free (error
);
104 g_warning ("unhandled status code %u from soup_socket_read()", (guint
) status
);
107 } while (status
== SOUP_SOCKET_OK
);
111 swfdec_gtk_socket_writable (SoupSocket
*sock
, SwfdecGtkSocket
*gtk
)
113 swfdec_socket_signal_writable (SWFDEC_SOCKET (gtk
));
117 swfdec_gtk_socket_do_connect (SoupSocket
*sock
, guint status
, gpointer gtk
)
119 if (SOUP_STATUS_IS_SUCCESSFUL (status
)) {
120 swfdec_stream_open (gtk
);
121 // need to read here, since readable signal will only be launched once the
122 // socket has been read until it's empty once
123 swfdec_gtk_socket_do_read (sock
, gtk
);
125 swfdec_stream_error (gtk
, "error connecting");
130 swfdec_gtk_socket_connect (SwfdecSocket
*sock_
, SwfdecPlayer
*player
,
131 const char *hostname
, guint port
)
133 SwfdecGtkSocket
*sock
= SWFDEC_GTK_SOCKET (sock_
);
136 addr
= soup_address_new (hostname
, port
);
137 sock
->sock
= soup_socket_new (
138 SOUP_SOCKET_FLAG_NONBLOCKING
, TRUE
,
139 SOUP_SOCKET_REMOTE_ADDRESS
, addr
, NULL
);
140 g_signal_connect (sock
->sock
, "disconnected",
141 G_CALLBACK (swfdec_gtk_socket_do_disconnect
), sock
);
142 g_signal_connect (sock
->sock
, "readable",
143 G_CALLBACK (swfdec_gtk_socket_do_read
), sock
);
144 g_signal_connect (sock
->sock
, "writable",
145 G_CALLBACK (swfdec_gtk_socket_writable
), sock
);
146 soup_socket_connect_async (sock
->sock
, NULL
, swfdec_gtk_socket_do_connect
, sock
);
150 swfdec_gtk_socket_send (SwfdecSocket
*sock
, SwfdecBuffer
*buffer
)
152 SwfdecGtkSocket
*gtk
= SWFDEC_GTK_SOCKET (sock
);
153 SoupSocketIOStatus status
;
154 GError
*error
= NULL
;
157 status
= soup_socket_write (gtk
->sock
, buffer
->data
, buffer
->length
,
161 case SOUP_SOCKET_WOULD_BLOCK
:
162 case SOUP_SOCKET_EOF
:
164 case SOUP_SOCKET_ERROR
:
165 swfdec_stream_error (SWFDEC_STREAM (gtk
), "%s", error
->message
);
166 g_error_free (error
);
169 g_warning ("unhandled status code %u from soup_socket_read()", (guint
) status
);
176 swfdec_gtk_socket_dispose (GObject
*object
)
178 SwfdecGtkSocket
*gtk
= SWFDEC_GTK_SOCKET (object
);
181 g_signal_handlers_disconnect_matched (gtk
->sock
, G_SIGNAL_MATCH_DATA
,
182 0, 0, NULL
, NULL
, gtk
);
183 g_object_unref (gtk
->sock
);
187 G_OBJECT_CLASS (swfdec_gtk_socket_parent_class
)->dispose (object
);
191 swfdec_gtk_socket_class_init (SwfdecGtkSocketClass
*klass
)
193 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
194 SwfdecStreamClass
*stream_class
= SWFDEC_STREAM_CLASS (klass
);
195 SwfdecSocketClass
*socket_class
= SWFDEC_SOCKET_CLASS (klass
);
197 object_class
->dispose
= swfdec_gtk_socket_dispose
;
199 stream_class
->close
= swfdec_gtk_socket_close
;
201 socket_class
->connect
= swfdec_gtk_socket_connect
;
202 socket_class
->send
= swfdec_gtk_socket_send
;
206 swfdec_gtk_socket_init (SwfdecGtkSocket
*gtk
)