# HG changeset patch # User Matti Hamalainen # Date 1218562189 -10800 # Node ID 6c53f9fa90290de68c1f03796507fb097f7f0ecc # Parent 59ff744e1e2395b7cc350d6d97feb72b566732a1 Backed out changeset 59ff744e1e23 diff -r 59ff744e1e23 -r 6c53f9fa9029 src/alsa/configure.c --- a/src/alsa/configure.c Fri Aug 01 22:55:49 2008 +0300 +++ b/src/alsa/configure.c Tue Aug 12 20:29:49 2008 +0300 @@ -40,19 +40,24 @@ alsa_cfg.mixer_card = current_mixer_card; alsa_cfg.mixer_device = GET_CHARS(GTK_COMBO(mixer_devices_combo)->entry); + gtk_widget_destroy(configure_win); + + /* Save configuration */ + mcs_handle_t *cfgfile = aud_cfg_db_open(); + aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "buffer_time", alsa_cfg.buffer_time); + aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "period_time", alsa_cfg.period_time); + aud_cfg_db_set_string(cfgfile,ALSA_CFGID,"pcm_device", alsa_cfg.pcm_device); + aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "mixer_card", alsa_cfg.mixer_card); + aud_cfg_db_set_string(cfgfile,ALSA_CFGID,"mixer_device", alsa_cfg.mixer_device); + aud_cfg_db_close(cfgfile); + + /* Save volumes */ alsa_save_config(); - gtk_widget_destroy(configure_win); } void alsa_save_config(void) { mcs_handle_t *cfgfile = aud_cfg_db_open(); - - aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "buffer_time", alsa_cfg.buffer_time); - aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "period_time", alsa_cfg.period_time); - aud_cfg_db_set_string(cfgfile,ALSA_CFGID,"pcm_device", alsa_cfg.pcm_device); - aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "mixer_card", alsa_cfg.mixer_card); - aud_cfg_db_set_string(cfgfile,ALSA_CFGID,"mixer_device", alsa_cfg.mixer_device); aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "volume_left", alsa_cfg.vol.left); aud_cfg_db_set_int(cfgfile, ALSA_CFGID, "volume_right", alsa_cfg.vol.right); aud_cfg_db_close(cfgfile); diff -r 59ff744e1e23 -r 6c53f9fa9029 src/bluetooth/bluetooth.c --- a/src/bluetooth/bluetooth.c Fri Aug 01 22:55:49 2008 +0300 +++ b/src/bluetooth/bluetooth.c Tue Aug 12 20:29:49 2008 +0300 @@ -16,9 +16,6 @@ * along with this program. If not, see . */ -#include -#include -#include #include "bluetooth.h" #include "marshal.h" #include "gui.h" @@ -30,7 +27,6 @@ gint config = 0; gint devices_no = 0; GStaticMutex mutex = G_STATIC_MUTEX_INIT; -static gchar *current_address=NULL; static GThread *connect_th; void bluetooth_init ( void ); void bluetooth_cleanup ( void ); @@ -67,8 +63,7 @@ void bluetooth_cleanup ( void ) { printf("bluetooth: exit\n"); - if (config ==1 ) - { + if (config ==1 ){ close_window(); config =0; } @@ -110,8 +105,7 @@ } -void clean_devices_list() -{ +void clean_devices_list(){ g_list_free(audio_devices); dbus_g_connection_flush (bus); dbus_g_connection_unref(bus); @@ -142,78 +136,15 @@ dbus_g_object_register_marshaller(marshal_VOID__STRING_UINT_INT, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INT, G_TYPE_INVALID); run_agents(); - dbus_g_proxy_call(obj,"CreateBonding",NULL,G_TYPE_STRING,current_address,G_TYPE_INVALID,G_TYPE_INVALID); - + dbus_g_proxy_call(obj,"CreateBonding",NULL,G_TYPE_STRING,((DeviceData*)(selected_dev->data))->address,G_TYPE_INVALID,G_TYPE_INVALID); + } void connect_call(void) { - current_address = g_strdup(((DeviceData*)(selected_dev->data))->address); - connect_th = g_thread_create((GThreadFunc)connect_call_th,NULL,TRUE,NULL) ; - close_call(); - close_window(); - show_scan(1); -} - - -void play_call() -{ - - FILE *file; - FILE *temp_file; - gint prev=0; - char line[128]; - gchar *home; - gchar *device_line; - gchar *file_name=""; - gchar *temp_file_name; - int ret = EOF+1; - home = g_get_home_dir(); - file_name = g_strconcat(home,"/.asoundrc",NULL); - temp_file_name = g_strconcat(home,"/temp_bt",NULL); - file = fopen(file_name,"r"); - temp_file = fopen(temp_file_name,"w"); - /* hardcoded address TO REMOVE after testing */ - // current_address = "00:0D:3C:B1:1C:7A"; - device_line = g_strdup_printf("device %s\n",current_address); - if ( file != NULL ) - { - while ( fgets ( line, sizeof line, file ) != NULL ) - { - if(!(strcmp(line,"pcm.audacious_bt {\n"))){ - fputs(line,temp_file); - fgets ( line, sizeof line, file ); /* type bluetooth */ - fputs(line,temp_file); - fgets ( line, sizeof line, file ); /* device MAC */ - fputs(device_line,temp_file); - prev = 1; - } else - fputs(line,temp_file); - } - - fclose (file); - } - if(!prev){ - fputs("pcm.audacious_bt{\n",temp_file); - fputs("type bluetooth\n",temp_file); - fputs(device_line,temp_file); - fputs("}\n",temp_file); - prev = 0; - } - - fclose(temp_file); - int err = rename(temp_file_name,file_name); - printf("rename error : %d",err); - perror("zz"); - g_free(device_line); - g_free(file_name); - g_free(temp_file_name); - mcs_handle_t *cfgfile = aud_cfg_db_open(); - aud_cfg_db_set_string(cfgfile,"ALSA","pcm_device", "audacious_bt"); - aud_cfg_db_close(cfgfile); - - printf("play callback\n"); - - + connect_th = g_thread_create((GThreadFunc)connect_call_th,NULL,TRUE,NULL) ; + close_call(); + close_window(); + show_scan(1); } diff -r 59ff744e1e23 -r 6c53f9fa9029 src/bluetooth/bluetooth.h --- a/src/bluetooth/bluetooth.h Fri Aug 01 22:55:49 2008 +0300 +++ b/src/bluetooth/bluetooth.h Tue Aug 12 20:29:49 2008 +0300 @@ -40,7 +40,6 @@ void refresh_call(void); void connect_call(void); -void play_call(void); GList * audio_devices; gint discover_finish ; DBusGConnection * bus; diff -r 59ff744e1e23 -r 6c53f9fa9029 src/bluetooth/scan_gui.c --- a/src/bluetooth/scan_gui.c Fri Aug 01 22:55:49 2008 +0300 +++ b/src/bluetooth/scan_gui.c Tue Aug 12 20:29:49 2008 +0300 @@ -31,58 +31,56 @@ static GtkWidget *close_button; static gint usage=0; -gpointer progress() -{ +gpointer progress() { for(;;){ if(window){ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress_bar)); } sleep(1); - if(usage == 0){ - if(discover_finish == 2 ) { - if(window){ - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar),1); - } - return 0; + if(usage == 0){ + if(discover_finish == 2 ) { + if(window){ + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar),1); } - }else - { - if(bonding_finish == 1 ) { - if(window){ - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar),1); - show_pairing_ok(); + return 0; + } + }else + { + if(bonding_finish == 1 ) { + if(window){ + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar),1); + show_pairing_ok(); + } + return 0; } - return 0; - } - } + } } return 0; } void show_pairing_ok() { - if(window ){ + if(window ){ gtk_label_set_text(GTK_LABEL(scan_label),_("Bonding finish!")); } } -void show_no_devices() -{ +void show_no_devices(){ if(window ){ gtk_label_set_text(GTK_LABEL(scan_label),_("No devices found!")); } } -void destroy_scan_window() -{ +void destroy_scan_window(){ gtk_widget_hide(window); } -void close_window(void) -{ +void close_window(void){ printf("scan_gui close callback \n"); gtk_widget_destroy (window); window = NULL; } + + void show_scan(gint use) { GThread *th1; @@ -115,9 +113,9 @@ if(usage == 0){ scan_label = gtk_label_new_with_mnemonic(_("Scanning...")); }else - { - scan_label = gtk_label_new_with_mnemonic(_("Pairing...")); - } + { + scan_label = gtk_label_new_with_mnemonic(_("Pairing...")); + } gtk_container_add(GTK_CONTAINER(scanbox),scan_label); @@ -131,15 +129,8 @@ /* I have to modify the rescan button with a play one * and treat the case when the bounding is not ok */ - if(usage == 0){ - rescan_buttton = gtk_button_new_with_mnemonic(_("Rescan")); - g_signal_connect(rescan_buttton,"clicked",G_CALLBACK (refresh_call),NULL); - }else{ - rescan_buttton = gtk_button_new_with_mnemonic(_("Play")); - g_signal_connect(rescan_buttton,"clicked",G_CALLBACK (play_call),NULL); - } - - + rescan_buttton = gtk_button_new_with_mnemonic(_("Rescan")); + g_signal_connect(rescan_buttton,"clicked",G_CALLBACK (refresh_call),NULL); close_button = gtk_button_new_with_mnemonic(_("Close")); gtk_container_add(GTK_CONTAINER(buttonsbox),rescan_buttton); diff -r 59ff744e1e23 -r 6c53f9fa9029 src/bluetooth/scan_gui.h --- a/src/bluetooth/scan_gui.h Fri Aug 01 22:55:49 2008 +0300 +++ b/src/bluetooth/scan_gui.h Tue Aug 12 20:29:49 2008 +0300 @@ -18,12 +18,6 @@ #include #include -#include -#include -#include -#include - - void show_scan(gint use); void show_no_devices(); void destroy_scan_window(); diff -r 59ff744e1e23 -r 6c53f9fa9029 src/streambrowser/gui/streambrowser_win.c --- a/src/streambrowser/gui/streambrowser_win.c Fri Aug 01 22:55:49 2008 +0300 +++ b/src/streambrowser/gui/streambrowser_win.c Tue Aug 12 20:29:49 2008 +0300 @@ -19,7 +19,7 @@ } streamdir_gui_t; -void (* update_function) (streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo); +void (* update_function) (streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo, gboolean add_to_playlist); static GtkWidget* gtk_label_new_with_icon(gchar *icon_filename, gchar *label_text); static GtkWidget* gtk_streamdir_tree_view_new(); @@ -33,7 +33,7 @@ static gboolean on_tree_view_button_pressed(GtkWidget *widget, GdkEventButton *event, gpointer data); static streamdir_gui_t* find_streamdir_gui_by_name(gchar *name); -static streamdir_gui_t* find_streamdir_gui_by_tree_view(GtkTreeView *tree_view); +//static streamdir_gui_t* find_streamdir_gui_by_tree_view(GtkTreeView *tree_view); todo: remove this static streamdir_gui_t* find_streamdir_gui_by_table(GtkTable *table); static streamdir_gui_t* find_streamdir_gui_by_streamdir(streamdir_t *streamdir); static gboolean tree_view_search_equal_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer data); @@ -46,6 +46,9 @@ static GtkCellRenderer* cell_renderer_pixbuf; static GtkCellRenderer* cell_renderer_text; +static gboolean tree_view_button_pressed = FALSE; + + void streambrowser_win_init() { @@ -186,13 +189,37 @@ streaminfo = streaminfo_get_by_index(category, i); gtk_tree_store_append(store, &new_iter, &iter); - gtk_tree_store_set(store, &new_iter, 0, "gtk-directory", 1, streaminfo->name, 2, streaminfo->current_track, -1); + gtk_tree_store_set(store, &new_iter, 0, "gtk-media-play", 1, streaminfo->name, 2, streaminfo->current_track, -1); } gtk_tree_path_free(path); } -void streambrowser_win_set_update_function(void (*function) (streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo)) +void streambrowser_win_set_streaminfo(streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo) +{ + streamdir_gui_t *streamdir_gui = find_streamdir_gui_by_name(streamdir->name); + if (streamdir_gui == NULL) { + failure("gui: streambrowser_win_set_category() called with non-existent streamdir\n"); + return; + } + + GtkTreeView *tree_view = GTK_TREE_VIEW(streamdir_gui->tree_view); + GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view))); + GtkTreePath *path; + GtkTreeIter iter, new_iter; + + /* find the corresponding streaminfo tree iter */ + path = gtk_tree_path_new_from_indices(category_get_index(streamdir, category), streaminfo_get_index(category, streaminfo), -1); + if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) + return; + + /* update the streaminfo*/ + gtk_tree_store_set(store, &new_iter, 0, "gtk-media-play", 1, streaminfo->name, 2, streaminfo->current_track, -1); + + gtk_tree_path_free(path); +} + +void streambrowser_win_set_update_function(void (*function) (streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo, gboolean add_to_playlist)) { update_function = function; } @@ -240,7 +267,7 @@ gtk_tree_store_set(store, &iter, 0, "gtk-refresh", 1, temp, 2, streaminfo->current_track, -1); } else { - gtk_tree_store_set(store, &iter, 0, "gtk-directory", 1, streaminfo->name, 2, streaminfo->current_track, -1); + gtk_tree_store_set(store, &iter, 0, "gtk-media-play", 1, streaminfo->name, 2, streaminfo->current_track, -1); } } @@ -330,53 +357,72 @@ return TRUE; } + static gboolean on_tree_view_cursor_changed(GtkTreeView *tree_view, gpointer data) { + /* only do the refresh if this cursor change occured due to a mouse click */ + if (!tree_view_button_pressed) + return FALSE; + + tree_view_button_pressed = FALSE; + GtkTreePath *path; - GtkTreeIter iter; - GtkTreeModel *model; + GtkTreeViewColumn *focus_column; + + /* get the currently selected tree view */ + GtkWidget *table = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))); + streamdir_gui_t *streamdir_gui = find_streamdir_gui_by_table(GTK_TABLE(table)); + if (streamdir_gui == NULL) + return FALSE; + + /* get the currently selected path in the tree */ + gtk_tree_view_get_cursor(tree_view, &path, &focus_column); + + if (path == NULL || gtk_tree_path_get_depth(path) == 0) + return FALSE; - /* obtain the current category */ - gtk_tree_view_get_cursor(tree_view, &path, NULL); - - if (path == NULL) - return TRUE; - gint *indices = gtk_tree_path_get_indices(path); - if (gtk_tree_path_get_depth(path) != 1) { + int category_index = indices[0]; + streamdir_t *streamdir = streamdir_gui->streamdir; + category_t *category = category_get_by_index(streamdir_gui->streamdir, category_index); + + /* if the selected item is a category */ + if (gtk_tree_path_get_depth(path) == 1) { + if (!gtk_tree_view_row_expanded(tree_view, path)) { + gtk_entry_set_text(GTK_ENTRY(search_entry), ""); + update_function(streamdir, category, NULL, FALSE); + } + gtk_tree_path_free(path); - return TRUE; + } + /* if the selected item is a streaminfo */ + else { + int streaminfo_index = indices[1]; + + gtk_tree_path_free(path); + + /* get the currently selected stream (info) */ + streaminfo_t *streaminfo = streaminfo_get_by_index(category, streaminfo_index); + + gtk_entry_set_text(GTK_ENTRY(search_entry), ""); + update_function(streamdir, category, streaminfo, FALSE); } - model = gtk_tree_view_get_model(tree_view); - gtk_tree_model_get_iter(model, &iter, path); - - /* don't fetch a category that has been already fetched */ - if (gtk_tree_model_iter_has_child(model, &iter)) { - gtk_tree_path_free(path); - return TRUE; - } - - int category_index = indices[0]; - - gtk_tree_path_free(path); - - streamdir_gui_t *streamdir_gui = find_streamdir_gui_by_tree_view(tree_view); - if (streamdir_gui == NULL) - return TRUE; - - /* issue an update on the current category */ - update_function(streamdir_gui->streamdir, category_get_by_index(streamdir_gui->streamdir, category_index), NULL); - - return TRUE; + return FALSE; } static gboolean on_tree_view_button_pressed(GtkWidget *widget, GdkEventButton *event, gpointer data) { /* double click adds the currently selected stream to the playlist */ if (event->type == GDK_2BUTTON_PRESS) { + tree_view_button_pressed = FALSE; on_add_button_clicked(NULL, NULL); } + /* single click triggers a refresh of the selected item */ + else { + // todo: separate single from double click somehow + tree_view_button_pressed = TRUE; + } return FALSE; } @@ -386,6 +432,7 @@ GtkTreePath *path; GtkTreeViewColumn *focus_column; + /* get the currently selected tree view */ GtkWidget *table = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))); streamdir_gui_t *streamdir_gui = find_streamdir_gui_by_table(GTK_TABLE(table)); if (streamdir_gui == NULL) @@ -393,6 +440,7 @@ GtkTreeView *tree_view = GTK_TREE_VIEW(streamdir_gui->tree_view); + /* get the currently selected path in the tree */ gtk_tree_view_get_cursor(tree_view, &path, &focus_column); if (path == NULL) @@ -414,12 +462,13 @@ gtk_tree_path_free(path); + /* get the currently selected stream (info) */ streamdir_t *streamdir = streamdir_gui->streamdir; category_t *category = category_get_by_index(streamdir_gui->streamdir, category_index); streaminfo_t *streaminfo = streaminfo_get_by_index(category, streaminfo_index); gtk_entry_set_text(GTK_ENTRY(search_entry), ""); - update_function(streamdir, category, streaminfo); + update_function(streamdir, category, streaminfo, TRUE); return TRUE; } @@ -470,6 +519,7 @@ return NULL; } +/* todo: remove this static streamdir_gui_t *find_streamdir_gui_by_tree_view(GtkTreeView *tree_view) { GList *iterator; @@ -484,6 +534,7 @@ return NULL; } +*/ static streamdir_gui_t *find_streamdir_gui_by_table(GtkTable *table) { diff -r 59ff744e1e23 -r 6c53f9fa9029 src/streambrowser/gui/streambrowser_win.h --- a/src/streambrowser/gui/streambrowser_win.h Fri Aug 01 22:55:49 2008 +0300 +++ b/src/streambrowser/gui/streambrowser_win.h Tue Aug 12 20:29:49 2008 +0300 @@ -12,7 +12,9 @@ void streambrowser_win_set_streamdir(streamdir_t *streamdir, gchar *icon_filename); void streambrowser_win_set_category(streamdir_t *streamdir, category_t *category); -void streambrowser_win_set_update_function(void (* update_function) (streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo)); +void streambrowser_win_set_streaminfo(streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo); + +void streambrowser_win_set_update_function(void (* update_function) (streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo, gboolean add_to_playlist)); void streambrowser_win_set_category_state(streamdir_t *streamdir, category_t *category, gboolean fetching); void streambrowser_win_set_streaminfo_state(streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo, gboolean fetching); diff -r 59ff744e1e23 -r 6c53f9fa9029 src/streambrowser/shoutcast.c --- a/src/streambrowser/shoutcast.c Fri Aug 01 22:55:49 2008 +0300 +++ b/src/streambrowser/shoutcast.c Tue Aug 12 20:29:49 2008 +0300 @@ -27,6 +27,78 @@ #include "shoutcast.h" +gboolean shoutcast_streaminfo_fetch(category_t *category, streaminfo_t *streaminfo) +{ + gchar url[DEF_STRING_LEN]; + g_snprintf(url, DEF_STRING_LEN, SHOUTCAST_CATEGORY_URL, category->name); + + /* generate a valid, temporary filename */ + char *temp_filename = tempnam(NULL, "aud_sb"); + if (temp_filename == NULL) { + failure("shoutcast: failed to create a temporary file\n"); + return FALSE; + } + + char temp_pathname[DEF_STRING_LEN]; + sprintf(temp_pathname, "file://%s", temp_filename); + + debug("shoutcast: fetching category file '%s'\n", url); + if (!fetch_remote_to_local_file(url, temp_pathname)) { + failure("shoutcast: category file '%s' could not be downloaded to '%s'\n", url, temp_pathname); + free(temp_filename); + return FALSE; + } + debug("shoutcast: category file '%s' successfuly downloaded to '%s'\n", url, temp_pathname); + + xmlDoc *doc = xmlReadFile(temp_pathname, NULL, 0); + if (doc == NULL) { + failure("shoutcast: failed to read '%s' category file\n", category->name); + free(temp_filename); + return FALSE; + } + + xmlNode *root_node = xmlDocGetRootElement(doc); + xmlNode *node; + + root_node = root_node->children; + + for (node = root_node; node != NULL; node = node->next) { + if (node->type == XML_ELEMENT_NODE && !strcmp((char *) node->name, "station")) { + gchar *streaminfo_name = (gchar*) xmlGetProp(node, (xmlChar *) "name"); + gchar *streaminfo_id = (gchar*) xmlGetProp(node, (xmlChar *) "id"); + gchar streaminfo_playlist_url[DEF_STRING_LEN]; + gchar *streaminfo_current_track = (gchar*) xmlGetProp(node, (xmlChar *) "ct"); + + g_snprintf(streaminfo_playlist_url, DEF_STRING_LEN, SHOUTCAST_STREAMINFO_URL, streaminfo_id); + + if (strncmp(streaminfo_playlist_url, streaminfo->playlist_url, DEF_STRING_LEN) == 0) { + debug("shoutcast: updating stream info for '%s/%d' from '%s'\n", streaminfo_name, streaminfo_id, url); + + strcpy(streaminfo->name, streaminfo_name); + strcpy(streaminfo->playlist_url, streaminfo_playlist_url); + strcpy(streaminfo->current_track, streaminfo_current_track); + + xmlFree(streaminfo_name); + xmlFree(streaminfo_id); + xmlFree(streaminfo_current_track); + + debug("shoutcast: stream info added\n"); + + break; + } + } + } + + xmlFreeDoc(doc); + + if (remove(temp_filename) != 0) { + failure("shoutcast: cannot remove the temporary file: %s\n", strerror(errno)); + } + free(temp_filename); + + return TRUE; +} + gboolean shoutcast_category_fetch(category_t *category) { gchar url[DEF_STRING_LEN]; @@ -75,7 +147,7 @@ g_snprintf(streaminfo_playlist_url, DEF_STRING_LEN, SHOUTCAST_STREAMINFO_URL, streaminfo_id); - debug("shoutcast: fetching stream info for '%s/%d' from '%s'\n", streaminfo_name, streaminfo_id, url); + debug("shoutcast: adding stream info for '%s/%d' from '%s'\n", streaminfo_name, streaminfo_id, url); streaminfo_t *streaminfo = streaminfo_new(streaminfo_name, streaminfo_playlist_url, "", streaminfo_current_track); streaminfo_add(category, streaminfo); diff -r 59ff744e1e23 -r 6c53f9fa9029 src/streambrowser/shoutcast.h --- a/src/streambrowser/shoutcast.h Fri Aug 01 22:55:49 2008 +0300 +++ b/src/streambrowser/shoutcast.h Tue Aug 12 20:29:49 2008 +0300 @@ -30,6 +30,7 @@ #define SHOUTCAST_STREAMINFO_URL "http://www.shoutcast.com/sbin/shoutcast-playlist.pls?rn=%s&file=filename.pls" +gboolean shoutcast_streaminfo_fetch(category_t *category, streaminfo_t *streaminfo); gboolean shoutcast_category_fetch(category_t *category); streamdir_t* shoutcast_streamdir_fetch(); diff -r 59ff744e1e23 -r 6c53f9fa9029 src/streambrowser/streambrowser.c --- a/src/streambrowser/streambrowser.c Fri Aug 01 22:55:49 2008 +0300 +++ b/src/streambrowser/streambrowser.c Tue Aug 12 20:29:49 2008 +0300 @@ -34,6 +34,7 @@ streamdir_t *streamdir; category_t *category; streaminfo_t *streaminfo; + gboolean add_to_playlist; } update_thread_data_t; @@ -47,7 +48,7 @@ static void config_load(); static void config_save(); -static void streamdir_update(streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo); +static void streamdir_update(streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo, gboolean add_to_playlist); static gpointer update_thread_core(gpointer user_data); static void streaminfo_add_to_playlist(streaminfo_t *streaminfo); static void on_plugin_services_menu_item_click(); @@ -271,12 +272,13 @@ debug("configuration saved\n"); } -static void streamdir_update(streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo) +static void streamdir_update(streamdir_t *streamdir, category_t *category, streaminfo_t *streaminfo, gboolean add_to_playlist) { - debug("requested streamdir update (streamdir = '%s', category = '%s', streaminfo = '%s')\n", + debug("requested streamdir update (streamdir = '%s', category = '%s', streaminfo = '%s', add_to_playlist = %d)\n", streamdir == NULL ? "" : streamdir->name, category == NULL ? "" : category->name, - streaminfo == NULL ? "" : streaminfo->name); + streaminfo == NULL ? "" : streaminfo->name, + add_to_playlist); if (g_queue_get_length(update_thread_data_queue) >= MAX_UPDATE_THREADS) { debug("another %d streamdir updates are pending, this request will be dropped\n", g_queue_get_length(update_thread_data_queue)); @@ -295,7 +297,8 @@ update_thread_data = g_queue_peek_nth(update_thread_data_queue, i); if (update_thread_data->streamdir == streamdir && update_thread_data->category == category && - update_thread_data->streaminfo == streaminfo) { + update_thread_data->streaminfo == streaminfo && + update_thread_data->add_to_playlist == add_to_playlist) { exists = TRUE; break; } @@ -310,6 +313,7 @@ update_thread_data->streamdir = streamdir; update_thread_data->category = category; update_thread_data->streaminfo = streaminfo; + update_thread_data->add_to_playlist = add_to_playlist; g_queue_push_tail(update_thread_data_queue, update_thread_data); } @@ -326,6 +330,7 @@ data->streamdir = streamdir; data->category = category; data->streaminfo = streaminfo; + data->add_to_playlist = add_to_playlist; g_queue_push_tail(update_thread_data_queue, data); @@ -350,46 +355,50 @@ /* repetitively process the queue elements, until queue is empty */ while (data != NULL && g_queue_get_length(update_thread_data_queue) > 0) { - /* update a streaminfo - that is - add this streaminfo to playlist */ + /* update a streaminfo */ if (data->streaminfo != NULL) { gdk_threads_enter(); streambrowser_win_set_streaminfo_state(data->streamdir, data->category, data->streaminfo, TRUE); gdk_threads_leave(); - streaminfo_add_to_playlist(data->streaminfo); + if (data->add_to_playlist) + streaminfo_add_to_playlist(data->streaminfo); + else { + /* shoutcast */ + if (strncmp(data->streamdir->name, SHOUTCAST_NAME, strlen(SHOUTCAST_NAME)) == 0) { + shoutcast_streaminfo_fetch(data->category, data->streaminfo); + } + /* xiph */ + else if (strncmp(data->streamdir->name, XIPH_NAME, strlen(XIPH_NAME)) == 0) { + xiph_streaminfo_fetch(data->category, data->streaminfo); + } + } gdk_threads_enter(); + if (!data->add_to_playlist) + streambrowser_win_set_streaminfo(data->streamdir, data->category, data->streaminfo); streambrowser_win_set_streaminfo_state(data->streamdir, data->category, data->streaminfo, FALSE); gdk_threads_leave(); } /* update a category */ else if (data->category != NULL) { + gdk_threads_enter(); + streambrowser_win_set_category_state(data->streamdir, data->category, TRUE); + gdk_threads_leave(); + /* shoutcast */ if (strncmp(data->streamdir->name, SHOUTCAST_NAME, strlen(SHOUTCAST_NAME)) == 0) { - gdk_threads_enter(); - streambrowser_win_set_category_state(data->streamdir, data->category, TRUE); - gdk_threads_leave(); - shoutcast_category_fetch(data->category); - - gdk_threads_enter(); - streambrowser_win_set_category(data->streamdir, data->category); - streambrowser_win_set_category_state(data->streamdir, data->category, FALSE); - gdk_threads_leave(); } /* xiph */ else if (strncmp(data->streamdir->name, XIPH_NAME, strlen(XIPH_NAME)) == 0) { - gdk_threads_enter(); - streambrowser_win_set_category_state(data->streamdir, data->category, TRUE); - gdk_threads_leave(); - xiph_category_fetch(data->category); + } - gdk_threads_enter(); - streambrowser_win_set_category(data->streamdir, data->category); - streambrowser_win_set_category_state(data->streamdir, data->category, FALSE); - gdk_threads_leave(); - } + gdk_threads_enter(); + streambrowser_win_set_category(data->streamdir, data->category); + streambrowser_win_set_category_state(data->streamdir, data->category, FALSE); + gdk_threads_leave(); } /* update a streamdir */ else if (data->streamdir != NULL) { @@ -466,7 +475,7 @@ } if (strlen(streaminfo->url) > 0) { - aud_playlist_add(aud_playlist_get_active(), streaminfo->url); + aud_playlist_add(aud_playlist_get_active(), streaminfo->url); debug("stream '%s' added\n", streaminfo->url); } } @@ -476,6 +485,6 @@ debug("on_plugin_services_menu_item_click()\n"); streambrowser_win_show(); - streamdir_update(NULL, NULL, NULL); + streamdir_update(NULL, NULL, NULL, FALSE); } diff -r 59ff744e1e23 -r 6c53f9fa9029 src/streambrowser/xiph.c --- a/src/streambrowser/xiph.c Fri Aug 01 22:55:49 2008 +0300 +++ b/src/streambrowser/xiph.c Tue Aug 12 20:29:49 2008 +0300 @@ -28,10 +28,12 @@ typedef struct { + gchar name[DEF_STRING_LEN]; gchar url[DEF_STRING_LEN]; gchar current_song[DEF_STRING_LEN]; gchar genre[DEF_STRING_LEN]; + } xiph_entry_t; @@ -39,8 +41,10 @@ static int xiph_entry_count = 0; typedef struct { + gchar *name; gchar *match_string; + } xiph_category_t; /* inspired from streamtuner's xiph plugin */ @@ -62,14 +66,34 @@ }; -// todo: call refresh_streamdir() more often to refresh the current track static void refresh_streamdir(); /* returns true if any of the words in string1 is present in string2 */ static gboolean genre_match(gchar *string1, gchar *string2); +gboolean xiph_streaminfo_fetch(category_t *category, streaminfo_t *streaminfo) +{ + int entryno; + + refresh_streamdir(); + + /* find the corresponding xiph entry */ + for (entryno = 0; entryno < xiph_entry_count; entryno++) { + if (strcmp(xiph_entries[entryno].name, streaminfo->name) == 0) { + strcpy(streaminfo->name, xiph_entries[entryno].name); + strcpy(streaminfo->url, xiph_entries[entryno].url); + strcpy(streaminfo->current_track, xiph_entries[entryno].current_song); + + break; + } + } + + return TRUE; +} gboolean xiph_category_fetch(category_t *category) { + refresh_streamdir(); + int entryno, categoryno; int xiph_category_count = sizeof(xiph_categories) / sizeof(xiph_category_t); xiph_category_t *xiph_category = NULL; @@ -139,8 +163,10 @@ static void refresh_streamdir() { /* free any previously fetched streamdir data */ - if (xiph_entries != NULL) + if (xiph_entries != NULL) { free(xiph_entries); + xiph_entries = NULL; + } xiph_entry_count = 0; debug("xiph: fetching streaming directory file '%s'\n", XIPH_STREAMDIR_URL); diff -r 59ff744e1e23 -r 6c53f9fa9029 src/streambrowser/xiph.h --- a/src/streambrowser/xiph.h Fri Aug 01 22:55:49 2008 +0300 +++ b/src/streambrowser/xiph.h Tue Aug 12 20:29:49 2008 +0300 @@ -29,6 +29,7 @@ #define XIPH_TEMP_FILENAME "file:///tmp/xiph_yp.xml" +gboolean xiph_streaminfo_fetch(category_t *category, streaminfo_t *streaminfo); gboolean xiph_category_fetch(category_t *category); streamdir_t* xiph_streamdir_fetch();