1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 * Implementation of DAAP (iTunes Music Sharing) source object
5 * Copyright (C) 2005 Charles Schmidt <cschmidt2@emich.edu>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program 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
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <glib/gi18n.h>
32 #include "eel-gconf-extensions.h"
33 #include "rb-daap-source.h"
34 #include "rb-stock-icons.h"
37 #include "rb-file-helpers.h"
38 #include "rb-dialog.h"
39 #include "rb-preferences.h"
41 #include "rb-daap-connection.h"
42 #include "rb-daap-mdns-browser.h"
43 #include "rb-daap-dialog.h"
45 #include "rb-static-playlist-source.h"
47 static void rb_daap_source_dispose (GObject
*object
);
48 static void rb_daap_source_set_property (GObject
*object
,
52 static void rb_daap_source_get_property (GObject
*object
,
56 static void rb_daap_source_activate (RBSource
*source
);
58 static gboolean
rb_daap_source_show_popup (RBSource
*source
);
59 static char * rb_daap_source_get_browser_key (RBSource
*source
);
60 static const char * rb_daap_source_get_paned_key (RBBrowserSource
*source
);
61 static void rb_daap_source_get_status (RBSource
*source
, char **text
, char **progress_text
, float *progress
);
62 static void rb_daap_source_cmd_disconnect (GtkAction
*action
, RBShell
*shell
);
63 static void rb_daap_source_disconnect (RBDAAPSource
*daap_source
);
65 #define CONF_ENABLE_BROWSING CONF_PREFIX "/sharing/enable_browsing"
66 #define CONF_STATE_SORTING CONF_PREFIX "/state/daap/sorting"
67 #define CONF_STATE_PANED_POSITION CONF_PREFIX "/state/daap/paned_position"
68 #define CONF_STATE_SHOW_BROWSER CONF_PREFIX "/state/daap/show_browser"
70 static RBDaapMdnsBrowser
*mdns_browser
= NULL
;
72 static GHashTable
*source_lookup
= NULL
;
74 static guint enable_browsing_notify_id
= EEL_GCONF_UNDEFINED_CONNECTION
;
76 static GdkPixbuf
*daap_share_pixbuf
= NULL
;
77 static GdkPixbuf
*daap_share_locked_pixbuf
= NULL
;
78 static gboolean daap_was_shutdown
= FALSE
;
80 struct RBDAAPSourcePrivate
82 GtkActionGroup
*action_group
;
87 gboolean password_protected
;
91 GSList
*playlist_sources
;
93 const char *connection_status
;
94 float connection_progress
;
96 gboolean disconnecting
;
104 PROP_PASSWORD_PROTECTED
107 G_DEFINE_TYPE (RBDAAPSource
, rb_daap_source
, RB_TYPE_BROWSER_SOURCE
)
109 static GtkActionEntry rb_daap_source_actions
[] =
111 { "DaapSourceDisconnect", GTK_STOCK_DISCONNECT
, N_("_Disconnect"), NULL
,
112 N_("Disconnect from DAAP share"),
113 G_CALLBACK (rb_daap_source_cmd_disconnect
) },
115 GtkActionGroup
*daap_action_group
;
116 guint daap_ui_merge_id
;
119 rb_daap_source_dispose (GObject
*object
)
121 RBDAAPSource
*source
= RB_DAAP_SOURCE (object
);
123 /* we should already have been disconnected */
124 g_assert (source
->priv
->connection
== NULL
);
126 G_OBJECT_CLASS (rb_daap_source_parent_class
)->dispose (object
);
130 rb_daap_source_finalize (GObject
*object
)
132 RBDAAPSource
*source
= RB_DAAP_SOURCE (object
);
134 g_free (source
->priv
->service_name
);
135 g_free (source
->priv
->host
);
137 G_OBJECT_CLASS (rb_daap_source_parent_class
)->finalize (object
);
141 rb_daap_source_class_init (RBDAAPSourceClass
*klass
)
143 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
144 RBSourceClass
*source_class
= RB_SOURCE_CLASS (klass
);
145 RBBrowserSourceClass
*browser_source_class
= RB_BROWSER_SOURCE_CLASS (klass
);
147 object_class
->dispose
= rb_daap_source_dispose
;
148 object_class
->finalize
= rb_daap_source_finalize
;
149 object_class
->get_property
= rb_daap_source_get_property
;
150 object_class
->set_property
= rb_daap_source_set_property
;
152 source_class
->impl_activate
= rb_daap_source_activate
;
153 source_class
->impl_can_search
= (RBSourceFeatureFunc
) rb_true_function
;
154 source_class
->impl_can_cut
= (RBSourceFeatureFunc
) rb_false_function
;
155 source_class
->impl_can_copy
= (RBSourceFeatureFunc
) rb_true_function
;
156 source_class
->impl_can_delete
= (RBSourceFeatureFunc
) rb_false_function
;
157 source_class
->impl_paste
= NULL
;
158 source_class
->impl_receive_drag
= NULL
;
159 source_class
->impl_delete
= NULL
;
160 source_class
->impl_show_popup
= rb_daap_source_show_popup
;
161 source_class
->impl_get_config_widget
= NULL
;
162 source_class
->impl_get_browser_key
= rb_daap_source_get_browser_key
;
163 source_class
->impl_get_status
= rb_daap_source_get_status
;
165 browser_source_class
->impl_get_paned_key
= rb_daap_source_get_paned_key
;
166 browser_source_class
->impl_has_drop_support
= (RBBrowserSourceFeatureFunc
) rb_false_function
;
168 g_object_class_install_property (object_class
,
170 g_param_spec_string ("service-name",
172 "mDNS/DNS-SD service name of the share",
174 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
));
176 g_object_class_install_property (object_class
,
178 g_param_spec_string ("host",
184 g_object_class_install_property (object_class
,
186 g_param_spec_uint ("port",
188 "Port of DAAP server on host",
193 g_object_class_install_property (object_class
,
194 PROP_PASSWORD_PROTECTED
,
195 g_param_spec_boolean ("password-protected",
196 "Password Protected",
197 "Whether the share is password protected",
201 g_type_class_add_private (klass
, sizeof (RBDAAPSourcePrivate
));
205 rb_daap_source_init (RBDAAPSource
*source
)
207 source
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (source
,
209 RBDAAPSourcePrivate
);
213 rb_daap_source_set_property (GObject
*object
,
218 RBDAAPSource
*source
= RB_DAAP_SOURCE (object
);
221 case PROP_SERVICE_NAME
:
222 source
->priv
->service_name
= g_value_dup_string (value
);
225 if (source
->priv
->host
) {
226 g_free (source
->priv
->host
);
228 source
->priv
->host
= g_value_dup_string (value
);
229 /* FIXME what do we do if its already connected and we
233 source
->priv
->port
= g_value_get_uint (value
);
235 case PROP_PASSWORD_PROTECTED
:
236 source
->priv
->password_protected
= g_value_get_boolean (value
);
239 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
245 rb_daap_source_get_property (GObject
*object
,
250 RBDAAPSource
*source
= RB_DAAP_SOURCE (object
);
253 case PROP_SERVICE_NAME
:
254 g_value_set_string (value
, source
->priv
->service_name
);
257 g_value_set_string (value
, source
->priv
->host
);
260 g_value_set_uint (value
, source
->priv
->port
);
262 case PROP_PASSWORD_PROTECTED
:
263 g_value_set_boolean (value
, source
->priv
->password_protected
);
266 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
272 rb_daap_get_icon (gboolean password_protected
,
277 g_return_val_if_fail (daap_share_pixbuf
!= NULL
, NULL
);
278 g_return_val_if_fail (daap_share_locked_pixbuf
!= NULL
, NULL
);
280 if (! password_protected
) {
281 icon
= g_object_ref (daap_share_pixbuf
);
282 } else if (connected
) {
283 icon
= g_object_ref (daap_share_pixbuf
);
285 icon
= g_object_ref (daap_share_locked_pixbuf
);
292 rb_daap_source_new (RBShell
*shell
,
293 const char *service_name
,
297 gboolean password_protected
)
300 RhythmDBEntryType type
;
304 g_object_get (shell
, "db", &db
, NULL
);
305 type
= rhythmdb_entry_register_type (db
, NULL
);
308 icon
= rb_daap_get_icon (password_protected
, FALSE
);
309 source
= RB_SOURCE (g_object_new (RB_TYPE_DAAP_SOURCE
,
310 "service-name", service_name
,
318 "sorting-key", CONF_STATE_SORTING
,
319 "password-protected", password_protected
,
320 "sourcelist-group", RB_SOURCELIST_GROUP_TRANSIENT
,
324 g_object_unref (icon
);
327 rb_shell_register_entry_type_for_source (shell
, source
,
334 find_source_by_service_name (const char *service_name
)
338 source
= g_hash_table_lookup (source_lookup
, service_name
);
344 mdns_service_added (RBDaapMdnsBrowser
*browser
,
345 const char *service_name
,
349 gboolean password_protected
,
355 g_message ("New service: %s name=%s host=%s port=%u password=%d",
356 service_name
, name
, host
, port
, password_protected
);
359 source
= find_source_by_service_name (service_name
);
361 if (source
== NULL
) {
362 source
= rb_daap_source_new (shell
, service_name
, name
, host
, port
, password_protected
);
363 g_hash_table_insert (source_lookup
, g_strdup (service_name
), source
);
364 rb_shell_append_source (shell
, source
, NULL
);
366 g_object_set (G_OBJECT (source
),
370 "password-protected", password_protected
,
376 mdns_service_removed (RBDaapMdnsBrowser
*browser
,
377 const char *service_name
,
382 source
= find_source_by_service_name (service_name
);
384 rb_debug ("DAAP source '%s' went away", service_name
);
385 if (source
== NULL
) {
389 g_hash_table_remove (source_lookup
, service_name
);
393 remove_source (RBSource
*source
)
395 rb_debug ("Removing DAAP source: %s", RB_DAAP_SOURCE (source
)->priv
->service_name
);
396 rb_daap_source_disconnect (RB_DAAP_SOURCE (source
));
397 rb_source_delete_thyself (source
);
401 start_browsing (RBShell
*shell
)
405 if (mdns_browser
!= NULL
) {
409 mdns_browser
= rb_daap_mdns_browser_new ();
410 if (mdns_browser
== NULL
) {
411 g_warning ("Unable to start mDNS browsing");
415 g_signal_connect_object (mdns_browser
,
417 G_CALLBACK (mdns_service_added
),
420 g_signal_connect_object (mdns_browser
,
422 G_CALLBACK (mdns_service_removed
),
427 rb_daap_mdns_browser_start (mdns_browser
, &error
);
429 g_warning ("Unable to start mDNS browsing: %s", error
->message
);
430 g_error_free (error
);
433 source_lookup
= g_hash_table_new_full ((GHashFunc
)g_str_hash
,
434 (GEqualFunc
)g_str_equal
,
435 (GDestroyNotify
)g_free
,
436 (GDestroyNotify
)remove_source
);
441 stop_browsing (RBShell
*shell
)
445 if (mdns_browser
== NULL
) {
449 rb_debug ("Destroying DAAP source lookup");
451 g_hash_table_destroy (source_lookup
);
452 source_lookup
= NULL
;
454 g_signal_handlers_disconnect_by_func (mdns_browser
, mdns_service_added
, shell
);
455 g_signal_handlers_disconnect_by_func (mdns_browser
, mdns_service_removed
, shell
);
458 rb_daap_mdns_browser_stop (mdns_browser
, &error
);
460 g_warning ("Unable to stop mDNS browsing: %s", error
->message
);
461 g_error_free (error
);
464 g_object_unref (mdns_browser
);
469 enable_browsing_changed_cb (GConfClient
*client
,
474 gboolean enabled
= eel_gconf_get_boolean (CONF_ENABLE_BROWSING
);
477 start_browsing (shell
);
479 stop_browsing (shell
);
484 composite_icons (const GdkPixbuf
*src1
,
485 const GdkPixbuf
*src2
)
497 dest
= gdk_pixbuf_copy (src1
);
503 w1
= gdk_pixbuf_get_width (src1
);
504 h1
= gdk_pixbuf_get_height (src1
);
505 w2
= gdk_pixbuf_get_width (src2
);
506 h2
= gdk_pixbuf_get_height (src2
);
508 do_scale
= ((float)w1
* 0.8) < w2
;
510 /* scale the emblem down if it will obscure the entire bottom image */
512 scaled
= gdk_pixbuf_scale_simple (src2
, w1
/ 2, h1
/ 2, GDK_INTERP_BILINEAR
);
514 scaled
= (GdkPixbuf
*)src2
;
517 w2
= gdk_pixbuf_get_width (scaled
);
518 h2
= gdk_pixbuf_get_height (scaled
);
523 gdk_pixbuf_composite (scaled
, dest
,
528 GDK_INTERP_BILINEAR
, 0xFF);
531 g_object_unref (scaled
);
538 create_pixbufs (void)
544 theme
= gtk_icon_theme_get_default ();
546 gtk_icon_size_lookup (GTK_ICON_SIZE_LARGE_TOOLBAR
, &size
, NULL
);
547 daap_share_pixbuf
= gtk_icon_theme_load_icon (theme
, "gnome-fs-network", size
, 0, NULL
);
549 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU
, &size
, NULL
);
550 emblem
= gtk_icon_theme_load_icon (theme
, "stock_lock", size
, 0, NULL
);
552 daap_share_locked_pixbuf
= composite_icons (daap_share_pixbuf
, emblem
);
554 if (emblem
!= NULL
) {
555 g_object_unref (emblem
);
560 destroy_pixbufs (void)
562 if (daap_share_pixbuf
!= NULL
) {
563 g_object_unref (daap_share_pixbuf
);
566 daap_share_pixbuf
= NULL
;
568 if (daap_share_locked_pixbuf
!= NULL
) {
569 g_object_unref (daap_share_locked_pixbuf
);
571 daap_share_locked_pixbuf
= NULL
;
575 rb_daap_sources_init (RBShell
*shell
)
577 gboolean enabled
= TRUE
;
579 GConfClient
*client
= eel_gconf_client_get_global ();
580 GtkUIManager
*uimanager
= NULL
;
582 value
= gconf_client_get_without_default (client
,
583 CONF_ENABLE_BROWSING
, NULL
);
585 enabled
= gconf_value_get_bool (value
);
586 gconf_value_free (value
);
589 g_object_ref (shell
);
592 start_browsing (shell
);
595 enable_browsing_notify_id
=
596 eel_gconf_notification_add (CONF_ENABLE_BROWSING
,
597 (GConfClientNotifyFunc
) enable_browsing_changed_cb
,
604 "ui-manager", &uimanager
,
606 daap_action_group
= gtk_action_group_new ("DaapActions");
607 gtk_action_group_set_translation_domain (daap_action_group
,
609 gtk_action_group_add_actions (daap_action_group
,
610 rb_daap_source_actions
, G_N_ELEMENTS (rb_daap_source_actions
),
612 gtk_ui_manager_insert_action_group (uimanager
, daap_action_group
, 0);
613 daap_ui_merge_id
= gtk_ui_manager_add_ui_from_file (uimanager
,
614 rb_file ("daap-ui.xml"),
616 g_object_unref (uimanager
);
622 rb_daap_sources_shutdown (RBShell
*shell
)
624 GtkUIManager
*uimanager
= NULL
;
626 rb_debug ("Shutting down DAAP sources");
628 g_assert (!daap_was_shutdown
);
629 daap_was_shutdown
= TRUE
;
632 "ui-manager", &uimanager
,
636 stop_browsing (shell
);
639 if (enable_browsing_notify_id
!= EEL_GCONF_UNDEFINED_CONNECTION
) {
640 eel_gconf_notification_remove (enable_browsing_notify_id
);
641 enable_browsing_notify_id
= EEL_GCONF_UNDEFINED_CONNECTION
;
644 gtk_ui_manager_remove_ui (uimanager
, daap_ui_merge_id
);
645 gtk_ui_manager_remove_action_group (uimanager
, daap_action_group
);
647 g_object_unref (uimanager
);
648 g_object_unref (shell
);
654 connection_auth_cb (RBDAAPConnection
*connection
,
661 parent
= GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (source
)));
662 password
= rb_daap_password_dialog_new_run (parent
, name
);
668 connection_connecting_cb (RBDAAPConnection
*connection
,
669 RBDAAPConnectionState state
,
671 RBDAAPSource
*source
)
674 gboolean is_connected
;
676 rb_debug ("DAAP connection status: %d/%f", state
, progress
);
680 case DAAP_GET_PASSWORD
:
682 source
->priv
->connection_status
= _("Connecting to music share");
684 case DAAP_GET_REVISION_NUMBER
:
685 case DAAP_GET_DB_INFO
:
687 case DAAP_GET_PLAYLISTS
:
688 case DAAP_GET_PLAYLIST_ENTRIES
:
689 source
->priv
->connection_status
= _("Retrieving songs from music share");
693 source
->priv
->connection_status
= NULL
;
697 source
->priv
->connection_progress
= progress
;
699 rb_source_notify_status_changed (RB_SOURCE (source
));
701 is_connected
= rb_daap_connection_is_connected (connection
);
702 icon
= rb_daap_get_icon (source
->priv
->password_protected
, is_connected
);
703 g_object_set (source
, "icon", icon
, NULL
);
705 g_object_unref (icon
);
710 connection_disconnected_cb (RBDAAPConnection
*connection
,
711 RBDAAPSource
*source
)
715 rb_debug ("DAAP connection disconnected");
717 if (daap_was_shutdown
) {
721 icon
= rb_daap_get_icon (source
->priv
->password_protected
, FALSE
);
722 g_object_set (source
, "icon", icon
, NULL
);
724 g_object_unref (icon
);
729 release_connection (RBDAAPSource
*daap_source
)
731 rb_debug ("Releasing connection");
733 g_object_unref (G_OBJECT (daap_source
->priv
->connection
));
734 /* Weak pointer will set to NULL for us */
735 /*daap_source->priv->connection = NULL;*/
739 rb_daap_source_connection_cb (RBDAAPConnection
*connection
,
744 RBDAAPSource
*daap_source
= RB_DAAP_SOURCE (source
);
745 RBShell
*shell
= NULL
;
748 RhythmDBEntryType entry_type
;
750 rb_debug ("Connection callback result: %s", result
? "success" : "failure");
752 if (result
== FALSE
) {
753 if (reason
!= NULL
) {
754 rb_error_dialog (NULL
, _("Could not connect to shared music"), "%s", reason
);
757 /* Don't release the connection if we are already disconnecting */
758 if (! daap_source
->priv
->disconnecting
) {
759 release_connection (daap_source
);
765 g_object_get (daap_source
,
767 "entry-type", &entry_type
,
769 playlists
= rb_daap_connection_get_playlists (RB_DAAP_CONNECTION (daap_source
->priv
->connection
));
770 for (l
= playlists
; l
!= NULL
; l
= g_slist_next (l
)) {
771 RBDAAPPlaylist
*playlist
= l
->data
;
772 RBSource
*playlist_source
;
774 playlist_source
= rb_static_playlist_source_new (shell
, playlist
->name
, FALSE
, entry_type
);
775 rb_static_playlist_source_add_locations (RB_STATIC_PLAYLIST_SOURCE (playlist_source
), playlist
->uris
);
777 rb_shell_append_source (shell
, playlist_source
, RB_SOURCE (daap_source
));
778 daap_source
->priv
->playlist_sources
= g_slist_prepend (daap_source
->priv
->playlist_sources
, playlist_source
);
781 g_object_unref (shell
);
782 g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE
, entry_type
);
786 rb_daap_source_activate (RBSource
*source
)
788 RBDAAPSource
*daap_source
= RB_DAAP_SOURCE (source
);
789 RBShell
*shell
= NULL
;
792 RhythmDBEntryType type
;
794 if (daap_source
->priv
->connection
!= NULL
) {
798 g_object_get (daap_source
,
803 g_object_get (shell
, "db", &db
, NULL
);
805 daap_source
->priv
->connection
= rb_daap_connection_new (name
,
806 daap_source
->priv
->host
,
807 daap_source
->priv
->port
,
808 daap_source
->priv
->password_protected
,
811 g_object_add_weak_pointer (G_OBJECT (daap_source
->priv
->connection
), (gpointer
*)&daap_source
->priv
->connection
);
813 rb_daap_connection_connect (RB_DAAP_CONNECTION (daap_source
->priv
->connection
),
814 (RBDAAPConnectionCallback
) rb_daap_source_connection_cb
,
818 g_object_unref (shell
);
821 g_signal_connect (daap_source
->priv
->connection
,
823 G_CALLBACK (connection_auth_cb
),
825 g_signal_connect (daap_source
->priv
->connection
,
827 G_CALLBACK (connection_connecting_cb
),
829 g_signal_connect (daap_source
->priv
->connection
,
831 G_CALLBACK (connection_disconnected_cb
),
836 rb_daap_source_disconnect_cb (RBDAAPConnection
*connection
,
841 RBDAAPSource
*daap_source
= RB_DAAP_SOURCE (source
);
843 rb_debug ("DAAP source disconnected");
845 release_connection (daap_source
);
847 g_object_unref (source
);
851 rb_daap_source_cmd_disconnect (GtkAction
*action
,
857 "selected-source", &source
,
860 if (!RB_IS_DAAP_SOURCE (source
)) {
861 g_critical ("got non-Daap source for Daap action");
865 rb_daap_source_disconnect (RB_DAAP_SOURCE (source
));
867 if (source
!= NULL
) {
868 g_object_unref (source
);
873 rb_daap_source_disconnect (RBDAAPSource
*daap_source
)
875 if (daap_source
->priv
->connection
) {
879 RhythmDBEntryType type
;
881 rb_debug ("Disconnecting source");
883 daap_source
->priv
->disconnecting
= TRUE
;
885 g_object_get (daap_source
, "shell", &shell
, "entry-type", &type
, NULL
);
886 g_object_get (shell
, "db", &db
, NULL
);
887 g_object_unref (shell
);
889 rhythmdb_entry_delete_by_type (db
, type
);
890 rhythmdb_commit (db
);
894 for (l
= daap_source
->priv
->playlist_sources
; l
!= NULL
; l
= l
->next
) {
895 RBSource
*playlist_source
= RB_SOURCE (l
->data
);
897 rb_source_delete_thyself (playlist_source
);
900 g_slist_free (daap_source
->priv
->playlist_sources
);
901 daap_source
->priv
->playlist_sources
= NULL
;
903 /* we don't want these firing while we are disconnecting */
904 g_signal_handlers_disconnect_by_func (daap_source
->priv
->connection
,
905 G_CALLBACK (connection_connecting_cb
),
907 g_signal_handlers_disconnect_by_func (daap_source
->priv
->connection
,
908 G_CALLBACK (connection_auth_cb
),
911 /* keep the source alive until the disconnect completes */
912 g_object_ref (daap_source
);
913 rb_daap_connection_disconnect (daap_source
->priv
->connection
,
914 (RBDAAPConnectionCallback
) rb_daap_source_disconnect_cb
,
917 /* wait until disconnected */
918 rb_debug ("Waiting for DAAP connection to finish");
919 while (daap_source
->priv
->connection
!= NULL
) {
920 rb_debug ("Waiting for DAAP connection to finish...");
921 gtk_main_iteration ();
927 rb_daap_source_show_popup (RBSource
*source
)
929 _rb_source_show_popup (RB_SOURCE (source
), "/DAAPSourcePopup");
934 source_host_find (const char *key
,
935 RBDAAPSource
*source
,
938 if (source
== NULL
|| host
== NULL
) {
942 if (strcmp (host
, source
->priv
->host
) == 0) {
950 rb_daap_source_find_for_uri (const char *uri
)
954 RBDAAPSource
*source
= NULL
;
960 ip
= strdup (uri
+ 7); /* daap:// */
961 s
= strchr (ip
, ':');
964 source
= (RBDAAPSource
*)g_hash_table_find (source_lookup
, (GHRFunc
)source_host_find
, ip
);
972 rb_daap_source_get_headers (RBDAAPSource
*source
,
979 if (bytes_out
!= NULL
) {
983 /* If there is no connection then bail */
984 if (source
->priv
->connection
== NULL
) {
991 RhythmDBEntry
*entry
;
994 g_object_get (source
, "shell", &shell
, NULL
);
995 g_object_get (shell
, "db", &db
, NULL
);
997 entry
= rhythmdb_entry_lookup_by_location (db
, uri
);
999 g_object_unref (shell
);
1000 g_object_unref (db
);
1002 bitrate
= rhythmdb_entry_get_ulong (entry
, RHYTHMDB_PROP_BITRATE
);
1003 /* bitrate is kilobits per second */
1004 /* a kilobit is 128 bytes */
1005 bytes
= (time
* bitrate
) * 128;
1008 if (bytes_out
!= NULL
) {
1012 return rb_daap_connection_get_headers (source
->priv
->connection
, uri
, bytes
);
1016 rb_daap_source_get_browser_key (RBSource
*source
)
1018 return g_strdup (CONF_STATE_SHOW_BROWSER
);
1022 rb_daap_source_get_paned_key (RBBrowserSource
*source
)
1024 return CONF_STATE_PANED_POSITION
;
1028 rb_daap_source_get_status (RBSource
*source
,
1030 char **progress_text
,
1033 RBDAAPSource
*daap_source
= RB_DAAP_SOURCE (source
);
1038 if (progress_text
!= NULL
) {
1039 *progress_text
= NULL
;
1041 if (progress
!= NULL
) {
1045 if (daap_source
->priv
->connection_status
!= NULL
) {
1047 *text
= g_strdup (daap_source
->priv
->connection_status
);
1050 if (progress
!= NULL
) {
1051 *progress
= daap_source
->priv
->connection_progress
;
1057 RB_SOURCE_CLASS (rb_daap_source_parent_class
)->impl_get_status (source
, text
, progress_text
, progress
);