~snaggen/rhythmbox/bpm

« back to all changes in this revision

Viewing changes to plugins/daap/rb-daap-mdns-publisher-howl.c

  • Committer: Jonathan Matthew
  • Author(s): Jonathan Matthew
  • Date: 2007-01-07 12:16:12 UTC
  • Revision ID: git-v1:5b6958ea3cf24f2c8bcfa15b9cab1fc7798b7305
Moved lots of files around. Now everything should be in the directory it's

2007-01-07  Jonathan Matthew  <jonathan@kaolin.wh9.net>

        Moved lots of files around.  Now everything should be in the directory
        it's built in and all plugin-specific files should be installed into
        the plugin directory.

        * plugins/audioscrobbler/rb-audioscrobbler-plugin.c:
        (impl_create_configure_dialog):
        * plugins/audioscrobbler/rb-audioscrobbler.c:
        (rb_audioscrobbler_class_init), (rb_audioscrobbler_dispose),
        (rb_audioscrobbler_finalize),
        (rb_audioscrobbler_get_config_widget):
        * plugins/audioscrobbler/rb-audioscrobbler.h:
        Use rb_plugin_find_file where needed.

        * widgets/rb-uri-dialog.c: (rb_uri_dialog_class_init),
        (rb_uri_dialog_init), (rb_uri_dialog_finalize),
        (rb_uri_dialog_new), (rb_uri_dialog_response_cb),
        (rb_uri_dialog_text_changed):
        * widgets/rb-uri-dialog.h:
        New common 'enter a URI' dialog, used by iradio and podcast code.

        * plugins/iradio/rb-iradio-plugin.c: (impl_activate):
        * plugins/iradio/rb-iradio-source.c:
        (rb_iradio_source_constructor), (rb_iradio_source_new),
        (impl_song_properties), (rb_iradio_source_first_time_changed),
        (new_station_location_added), (rb_iradio_source_cmd_new_station):
        * plugins/iradio/rb-iradio-source.h:
        * plugins/iradio/rb-station-properties-dialog.c:
        (rb_station_properties_dialog_class_init),
        (rb_station_properties_dialog_init),
        (rb_station_properties_dialog_constructor),
        (rb_station_properties_dialog_set_property),
        (rb_station_properties_dialog_get_property),
        (rb_station_properties_dialog_new):
        * plugins/iradio/rb-station-properties-dialog.h:
        Use the common URI dialog, use rb_plugin_find_file where needed.

        * sources/rb-podcast-source.c:
        (rb_podcast_source_location_added_cb),
        (rb_podcast_source_cmd_new_podcast):
        Use the common URI dialog.

svn path=/trunk/; revision=4725

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 
2
 *
 
3
 *  Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
 
4
 *  Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
19
 *
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <stdlib.h>
 
25
#include <stdio.h>
 
26
 
 
27
#include <glib.h>
 
28
#include <glib/gi18n.h>
 
29
#include <glib-object.h>
 
30
 
 
31
/* stupid howl includes howl_config.h */
 
32
#undef PACKAGE
 
33
#undef VERSION
 
34
#include <howl.h>
 
35
 
 
36
#include "rb-daap-mdns-publisher.h"
 
37
#include "rb-debug.h"
 
38
 
 
39
static void     rb_daap_mdns_publisher_class_init (RBDaapMdnsPublisherClass *klass);
 
40
static void     rb_daap_mdns_publisher_init       (RBDaapMdnsPublisher      *publisher);
 
41
static void     rb_daap_mdns_publisher_finalize   (GObject                  *object);
 
42
 
 
43
#define RB_DAAP_MDNS_PUBLISHER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DAAP_MDNS_PUBLISHER, RBDaapMdnsPublisherPrivate))
 
44
 
 
45
struct RBDaapMdnsPublisherPrivate
 
46
{
 
47
        sw_discovery     *discovery;
 
48
        sw_discovery_oid *oid;
 
49
 
 
50
        guint             watch_id;
 
51
 
 
52
        char             *name;
 
53
        guint             port;
 
54
        gboolean          password_required;
 
55
};
 
56
 
 
57
enum {
 
58
        PUBLISHED,
 
59
        NAME_COLLISION,
 
60
        LAST_SIGNAL
 
61
};
 
62
 
 
63
enum {
 
64
        PROP_0
 
65
};
 
66
 
 
67
static guint         signals [LAST_SIGNAL] = { 0, };
 
68
 
 
69
G_DEFINE_TYPE (RBDaapMdnsPublisher, rb_daap_mdns_publisher, G_TYPE_OBJECT)
 
70
 
 
71
static gpointer publisher_object = NULL;
 
72
 
 
73
GQuark
 
74
rb_daap_mdns_publisher_error_quark (void)
 
75
{
 
76
        static GQuark quark = 0;
 
77
        if (!quark)
 
78
                quark = g_quark_from_static_string ("rb_daap_mdns_publisher_error");
 
79
 
 
80
        return quark;
 
81
}
 
82
 
 
83
static gboolean
 
84
howl_in_cb (GIOChannel          *io_channel,
 
85
            GIOCondition         condition,
 
86
            RBDaapMdnsPublisher *publisher)
 
87
{
 
88
        sw_salt salt;
 
89
 
 
90
        if (sw_discovery_salt (*publisher->priv->discovery, &salt) == SW_OKAY) {
 
91
                sw_salt_lock (salt);
 
92
                sw_discovery_read_socket (*publisher->priv->discovery);
 
93
                sw_salt_unlock (salt);
 
94
        }
 
95
 
 
96
        return TRUE;
 
97
}
 
98
 
 
99
static void
 
100
howl_client_init (RBDaapMdnsPublisher *publisher)
 
101
{
 
102
        sw_result   result;
 
103
        int         fd;
 
104
        GIOChannel *channel;
 
105
 
 
106
        publisher->priv->discovery = g_new0 (sw_discovery, 1);
 
107
        result = sw_discovery_init (publisher->priv->discovery);
 
108
 
 
109
        if (result != SW_OKAY) {
 
110
                g_free (publisher->priv->discovery);
 
111
                publisher->priv->discovery = NULL;
 
112
                return;
 
113
        }
 
114
 
 
115
        fd = sw_discovery_socket (*publisher->priv->discovery);
 
116
 
 
117
        channel = g_io_channel_unix_new (fd);
 
118
        publisher->priv->watch_id = g_io_add_watch (channel, G_IO_IN, (GIOFunc)howl_in_cb, publisher);
 
119
        g_io_channel_unref (channel);
 
120
}
 
121
 
 
122
static sw_result
 
123
publish_cb (sw_discovery                discovery,
 
124
            sw_discovery_oid            oid,
 
125
            sw_discovery_publish_status status,
 
126
            RBDaapMdnsPublisher        *publisher)
 
127
{
 
128
        if (status == SW_DISCOVERY_PUBLISH_STARTED) {
 
129
                g_signal_emit (publisher, signals [PUBLISHED], 0, publisher->priv->name);
 
130
        } else if (status == SW_DISCOVERY_PUBLISH_NAME_COLLISION) {
 
131
                /* This is all well and good, but howl won't report a name collision.
 
132
                 * http://lists.porchdogsoft.com/pipermail/howl-users/Week-of-Mon-20041206/000487.html
 
133
                 * So.  Fuck.
 
134
                 */
 
135
                g_warning ("MDNS name collision");
 
136
 
 
137
                g_signal_emit (publisher, signals [NAME_COLLISION], 0, publisher->priv->name);
 
138
        }
 
139
 
 
140
        return SW_OKAY;
 
141
}
 
142
 
 
143
static const char *
 
144
howl_strerror (sw_result result)
 
145
{
 
146
        const char *str;
 
147
 
 
148
        switch (result) {
 
149
                case SW_OKAY:
 
150
                        str = "No error";
 
151
                case SW_DISCOVERY_E_NO_MEM:
 
152
                        str = "Out of memory";
 
153
                case SW_DISCOVERY_E_BAD_PARAM:
 
154
                        str = "Invalid paramater";
 
155
                case SW_DISCOVERY_E_UNKNOWN:
 
156
                default:
 
157
                        str = "Unknown error";
 
158
        }
 
159
 
 
160
        return str;
 
161
}
 
162
 
 
163
static gboolean
 
164
create_service (RBDaapMdnsPublisher *publisher,
 
165
                GError             **error)
 
166
{
 
167
        sw_text_record text_record;
 
168
        sw_result      result;
 
169
 
 
170
        if (sw_text_record_init (&text_record) != SW_OKAY) {
 
171
                rb_debug ("Error initializing Howl text record");
 
172
                g_set_error (error,
 
173
                             RB_DAAP_MDNS_PUBLISHER_ERROR,
 
174
                             RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
 
175
                             "%s",
 
176
                             _("Error initializing Howl for publishing"));
 
177
                return FALSE;
 
178
        }
 
179
 
 
180
        if (publisher->priv->oid != NULL) {
 
181
                rb_daap_mdns_publisher_withdraw (publisher, NULL);
 
182
        }
 
183
 
 
184
        publisher->priv->oid = g_new0 (sw_discovery_oid, 1);
 
185
 
 
186
        sw_text_record_add_key_and_string_value (text_record,
 
187
                                                 "Password",
 
188
                                                 publisher->priv->password_required ? "true" : "false");
 
189
 
 
190
        result = sw_discovery_publish (*publisher->priv->discovery,
 
191
                                       0,
 
192
                                       publisher->priv->name,
 
193
                                       "_daap._tcp",
 
194
                                       "local",
 
195
                                       NULL,
 
196
                                       publisher->priv->port,
 
197
                                       sw_text_record_bytes (text_record),
 
198
                                       sw_text_record_len (text_record),
 
199
                                       (sw_discovery_publish_reply) publish_cb,
 
200
                                       (sw_opaque) publisher,
 
201
                                       (sw_discovery_oid *) publisher->priv->oid);
 
202
 
 
203
        sw_text_record_fina (text_record);
 
204
 
 
205
        if (result != SW_OKAY) {
 
206
                rb_debug ("Error starting mDNS publish with Howl: %s", howl_strerror (result));
 
207
                g_set_error (error,
 
208
                             RB_DAAP_MDNS_PUBLISHER_ERROR,
 
209
                             RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
 
210
                             "%s: %s",
 
211
                             _("Error initializing Howl for publishing"),
 
212
                             howl_strerror (result));
 
213
                return FALSE;
 
214
        }
 
215
 
 
216
        return TRUE;
 
217
}
 
218
 
 
219
static gboolean
 
220
refresh_service (RBDaapMdnsPublisher *publisher,
 
221
                 GError             **error)
 
222
{
 
223
        return create_service (publisher, error);
 
224
}
 
225
 
 
226
gboolean
 
227
rb_daap_mdns_publisher_publish (RBDaapMdnsPublisher *publisher,
 
228
                                const char          *name,
 
229
                                guint                port,
 
230
                                gboolean             password_required,
 
231
                                GError             **error)
 
232
{
 
233
        if (publisher->priv->discovery == NULL) {
 
234
                g_set_error (error,
 
235
                             RB_DAAP_MDNS_PUBLISHER_ERROR,
 
236
                             RB_DAAP_MDNS_PUBLISHER_ERROR_NOT_RUNNING,
 
237
                             "%s",
 
238
                             _("The howl MDNS service is not running"));
 
239
                return FALSE;
 
240
        }
 
241
 
 
242
        rb_daap_mdns_publisher_set_name (publisher, name, NULL);
 
243
        rb_daap_mdns_publisher_set_port (publisher, port, NULL);
 
244
        rb_daap_mdns_publisher_set_password_required (publisher, password_required, NULL);
 
245
 
 
246
        /* special case: the _set_ functions have updated the existing entry group */
 
247
        if (publisher->priv->oid != NULL) {
 
248
                return TRUE;
 
249
        }
 
250
 
 
251
        return create_service (publisher, error);
 
252
}
 
253
 
 
254
gboolean
 
255
rb_daap_mdns_publisher_withdraw (RBDaapMdnsPublisher *publisher,
 
256
                                 GError             **error)
 
257
{
 
258
        if (publisher->priv->discovery == NULL) {
 
259
                g_set_error (error,
 
260
                             RB_DAAP_MDNS_PUBLISHER_ERROR,
 
261
                             RB_DAAP_MDNS_PUBLISHER_ERROR_NOT_RUNNING,
 
262
                             "%s",
 
263
                             _("The howl MDNS service is not running"));
 
264
                return FALSE;
 
265
        }
 
266
 
 
267
        if (publisher->priv->oid == NULL) {
 
268
                g_set_error (error,
 
269
                             RB_DAAP_MDNS_PUBLISHER_ERROR,
 
270
                             RB_DAAP_MDNS_PUBLISHER_ERROR_FAILED,
 
271
                             "%s",
 
272
                             _("The MDNS service is not published"));
 
273
                return FALSE;
 
274
        }
 
275
 
 
276
        sw_discovery_cancel (*publisher->priv->discovery, *publisher->priv->oid);
 
277
 
 
278
        g_free (publisher->priv->oid);
 
279
        publisher->priv->oid = NULL;
 
280
 
 
281
        return TRUE;
 
282
}
 
283
 
 
284
gboolean
 
285
rb_daap_mdns_publisher_set_name (RBDaapMdnsPublisher *publisher,
 
286
                                 const char          *name,
 
287
                                 GError             **error)
 
288
{
 
289
        g_return_val_if_fail (publisher != NULL, FALSE);
 
290
 
 
291
        g_free (publisher->priv->name);
 
292
        publisher->priv->name = g_strdup (name);
 
293
 
 
294
        if (publisher->priv->oid) {
 
295
                refresh_service (publisher, error);
 
296
        }
 
297
 
 
298
        return TRUE;
 
299
}
 
300
gboolean
 
301
rb_daap_mdns_publisher_set_port (RBDaapMdnsPublisher *publisher,
 
302
                                 guint                port,
 
303
                                 GError             **error)
 
304
{
 
305
        g_return_val_if_fail (publisher != NULL, FALSE);
 
306
 
 
307
        publisher->priv->port = port;
 
308
 
 
309
        if (publisher->priv->oid) {
 
310
                refresh_service (publisher, error);
 
311
        }
 
312
 
 
313
        return TRUE;
 
314
}
 
315
gboolean
 
316
rb_daap_mdns_publisher_set_password_required (RBDaapMdnsPublisher *publisher,
 
317
                                              gboolean             required,
 
318
                                              GError             **error)
 
319
{
 
320
        g_return_val_if_fail (publisher != NULL, FALSE);
 
321
 
 
322
        publisher->priv->password_required = required;
 
323
 
 
324
        if (publisher->priv->oid) {
 
325
                refresh_service (publisher, error);
 
326
        }
 
327
 
 
328
        return TRUE;
 
329
}
 
330
 
 
331
static void
 
332
rb_daap_mdns_publisher_set_property (GObject      *object,
 
333
                                     guint         prop_id,
 
334
                                     const GValue *value,
 
335
                                     GParamSpec   *pspec)
 
336
{
 
337
        switch (prop_id) {
 
338
        default:
 
339
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
340
                break;
 
341
        }
 
342
}
 
343
 
 
344
static void
 
345
rb_daap_mdns_publisher_get_property (GObject     *object,
 
346
                                     guint        prop_id,
 
347
                                     GValue      *value,
 
348
                                     GParamSpec  *pspec)
 
349
{
 
350
        switch (prop_id) {
 
351
        default:
 
352
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
353
                break;
 
354
        }
 
355
}
 
356
 
 
357
static void
 
358
rb_daap_mdns_publisher_class_init (RBDaapMdnsPublisherClass *klass)
 
359
{
 
360
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
361
 
 
362
        object_class->finalize     = rb_daap_mdns_publisher_finalize;
 
363
        object_class->get_property = rb_daap_mdns_publisher_get_property;
 
364
        object_class->set_property = rb_daap_mdns_publisher_set_property;
 
365
 
 
366
        signals [PUBLISHED] =
 
367
                g_signal_new ("published",
 
368
                              G_TYPE_FROM_CLASS (object_class),
 
369
                              G_SIGNAL_RUN_LAST,
 
370
                              G_STRUCT_OFFSET (RBDaapMdnsPublisherClass, published),
 
371
                              NULL,
 
372
                              NULL,
 
373
                              g_cclosure_marshal_VOID__STRING,
 
374
                              G_TYPE_NONE,
 
375
                              1, G_TYPE_STRING);
 
376
        signals [NAME_COLLISION] =
 
377
                g_signal_new ("name-collision",
 
378
                              G_TYPE_FROM_CLASS (object_class),
 
379
                              G_SIGNAL_RUN_LAST,
 
380
                              G_STRUCT_OFFSET (RBDaapMdnsPublisherClass, name_collision),
 
381
                              NULL,
 
382
                              NULL,
 
383
                              g_cclosure_marshal_VOID__STRING,
 
384
                              G_TYPE_NONE,
 
385
                              1, G_TYPE_STRING);
 
386
 
 
387
        g_type_class_add_private (klass, sizeof (RBDaapMdnsPublisherPrivate));
 
388
}
 
389
 
 
390
static void
 
391
rb_daap_mdns_publisher_init (RBDaapMdnsPublisher *publisher)
 
392
{
 
393
        publisher->priv = RB_DAAP_MDNS_PUBLISHER_GET_PRIVATE (publisher);
 
394
 
 
395
        howl_client_init (publisher);
 
396
}
 
397
 
 
398
static void
 
399
rb_daap_mdns_publisher_finalize (GObject *object)
 
400
{
 
401
        RBDaapMdnsPublisher *publisher;
 
402
 
 
403
        g_return_if_fail (object != NULL);
 
404
        g_return_if_fail (RB_IS_DAAP_MDNS_PUBLISHER (object));
 
405
 
 
406
        publisher = RB_DAAP_MDNS_PUBLISHER (object);
 
407
 
 
408
        g_return_if_fail (publisher->priv != NULL);
 
409
 
 
410
        if (publisher->priv->oid) {
 
411
                rb_daap_mdns_publisher_withdraw (publisher, NULL);
 
412
        }
 
413
 
 
414
        if (publisher->priv->discovery) {
 
415
                sw_discovery_fina (*publisher->priv->discovery);
 
416
                g_free (publisher->priv->discovery);
 
417
        }
 
418
 
 
419
        if (publisher->priv->watch_id > 0) {
 
420
                g_source_remove (publisher->priv->watch_id);
 
421
        }
 
422
 
 
423
        g_free (publisher->priv->name);
 
424
 
 
425
        G_OBJECT_CLASS (rb_daap_mdns_publisher_parent_class)->finalize (object);
 
426
}
 
427
 
 
428
RBDaapMdnsPublisher *
 
429
rb_daap_mdns_publisher_new (void)
 
430
{
 
431
        if (publisher_object) {
 
432
                g_object_ref (publisher_object);
 
433
        } else {
 
434
                publisher_object = g_object_new (RB_TYPE_DAAP_MDNS_PUBLISHER, NULL);
 
435
                g_object_add_weak_pointer (publisher_object,
 
436
                                           (gpointer *) &publisher_object);
 
437
        }
 
438
 
 
439
        return RB_DAAP_MDNS_PUBLISHER (publisher_object);
 
440
}