changeset 2914:457260d55428

Automated merge with ssh://hg.atheme-project.org//hg//audacious-plugins
author Calin Crisan ccrisan@gmail.com
date Fri, 15 Aug 2008 16:00:53 +0200
parents 8f0a8a0d71c5 (diff) 113454baecf8 (current diff)
children 703cd5256849
files
diffstat 9 files changed, 265 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/src/bluetooth/agent.c	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/bluetooth/agent.c	Fri Aug 15 16:00:53 2008 +0200
@@ -700,7 +700,7 @@
 static void bonding_created(DBusGProxy *object,
 				const char *address, gpointer user_data)
 {
-    bonded_dev_mutex = g_mutex_new (); 
+
 
 	const char *adapter = NULL, *name = NULL;
 	gchar *device, *text;
@@ -719,10 +719,8 @@
 			device = g_strdup_printf("%s (%s)", name, address);
 	} else
 		device = g_strdup(address);
-    
-    g_mutex_lock(bonded_dev_mutex);
-    bonded_dev = g_strdup_printf(address);
-    g_mutex_unlock(bonded_dev_mutex);
+       bonded_dev = g_strdup_printf(address);
+
 
 	text = g_strdup_printf(_("Created bonding with %s"), device);
     bonding_finish = 1;
@@ -756,7 +754,7 @@
 	text = g_strdup_printf(_("Removed bonding with %s"), device);
 
 	g_free(device);
-    printf("bonding removed");
+    printf("bonding removed\n");
 
 //	show_notification(adapter ? adapter : _("Bluetooth device"),
 //						text, NULL, 6000, NULL);
--- a/src/bluetooth/bluetooth.c	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/bluetooth/bluetooth.c	Fri Aug 15 16:00:53 2008 +0200
@@ -156,19 +156,17 @@
 
     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();
-    close_call();
-    show_scan(1);
-
     dbus_g_proxy_call(obj,"CreateBonding",NULL,G_TYPE_STRING,current_address,G_TYPE_INVALID,G_TYPE_INVALID); 
     return NULL;
 }
 void connect_call(void)
-{
+{   close_call();
+    close_window();
+    show_scan(1);
+    remove_bonding();
     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);
+
 }
 
 
--- a/src/icecast/icecast.c	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/icecast/icecast.c	Fri Aug 15 16:00:53 2008 +0200
@@ -32,6 +32,7 @@
 static GtkWidget *configure_win = NULL, *configure_vbox;
 static GtkWidget *addr_entry, *port_spin, *timeout_spin, *buffersize_spin, *bufferflush_spin;
 static GtkWidget *user_entry, *password_entry, *mount_entry;
+static GtkWidget *public_check, *name_entry, *url_entry, *genre_entry, *description_entry;
 static GtkWidget *configure_bbox, *configure_ok, *configure_cancel;
 static guint ice_tid = 0;
 
@@ -78,6 +79,15 @@
 static gchar *server_password = NULL;
 static gchar *mountpoint = NULL;
 
+static gint stream_is_public = 0;
+static gchar *stream_name = NULL;
+static gchar *stream_url = NULL;
+static gchar *stream_genre = NULL;
+static gchar *stream_description = NULL;
+
+static gboolean initialized = FALSE;
+static gboolean ep_playing = FALSE;
+
 VFSFile *output_file = NULL;
 guint64 written = 0;
 guint64 offset = 0;
@@ -92,6 +102,7 @@
 static void ice_write(void *ptr, gint length);
 static gint ice_write_output(void *ptr, gint length);
 static void ice_close(void);
+static gboolean ice_real_close(gpointer data);
 static void ice_flush(gint time);
 static void ice_pause(short p);
 static gint ice_free(void);
@@ -99,11 +110,11 @@
 static gint ice_get_written_time(void);
 static gint ice_get_output_time(void);
 static void ice_configure(void);
-/*static int ice_mod_samples(gpointer * d, gint length, AFormat afmt, gint srate, gint nch);*/
+static int ice_mod_samples(gpointer * d, gint length, AFormat afmt, gint srate, gint nch);
 
 OutputPlugin ice_op =
 {
-    .description = "Icecast Plugin",
+    .description = "Icecast Plugin (output)",
     .init = ice_init,
     .cleanup = ice_cleanup,
     .about = ice_about,
@@ -118,20 +129,22 @@
     .output_time = ice_get_output_time,
     .written_time = ice_get_written_time
 };
-/*
+
 EffectPlugin ice_ep =
 {
-        .description = "Icecast Plugin",
-        .init = ice_init,
-        .cleanup = ice_cleanup,
+        .description = "Icecast Plugin (effect)",
+        .init = NULL,
+        .cleanup = NULL,
         .about = ice_about,
         .configure = ice_configure,
         .mod_samples = ice_mod_samples,
 };
-*/
+
 OutputPlugin *ice_oplist[] = { &ice_op, NULL };
 
-SIMPLE_OUTPUT_PLUGIN(icecast, ice_oplist);
+EffectPlugin *ice_eplist[] = { &ice_ep, NULL };
+
+DECLARE_PLUGIN(icecast, NULL, NULL, NULL, ice_oplist, ice_eplist, NULL, NULL, NULL, NULL)
 
 static void set_plugin(void)
 {
@@ -152,6 +165,7 @@
 {
     ConfigDb *db;
     g_debug("ICE_INIT");
+    if (initialized==TRUE) return;
     shout_init();
     g_message("Using libshout %s", shout_version(NULL, NULL, NULL));
 
@@ -176,6 +190,11 @@
     aud_cfg_db_get_string(db, ICECAST_CFGID, "server_user", &server_user);
     aud_cfg_db_get_string(db, ICECAST_CFGID, "server_password", &server_password);
     aud_cfg_db_get_string(db, ICECAST_CFGID, "mountpoint", &mountpoint);
+    aud_cfg_db_get_int(db, ICECAST_CFGID, "stream_is_public", &stream_is_public);
+    aud_cfg_db_get_string(db, ICECAST_CFGID, "stream_name", &stream_name);
+    aud_cfg_db_get_string(db, ICECAST_CFGID, "stream_url", &stream_url);
+    aud_cfg_db_get_string(db, ICECAST_CFGID, "stream_genre", &stream_genre);
+    aud_cfg_db_get_string(db, ICECAST_CFGID, "stream_description", &stream_description);
     aud_cfg_db_close(db);
 
     outputbuffer = g_try_malloc(buffersize);
@@ -184,10 +203,13 @@
     plugin = plugin_new;
     if (plugin.init)
         plugin.init(&ice_write_output);
+
+    initialized = TRUE;
 }
 
 static void ice_cleanup(void)
 {
+    if (initialized==FALSE) return;
     if (shout)
     {
         shout_close(shout);
@@ -229,6 +251,9 @@
     gint pos;
     Playlist *playlist;
 
+    if (ep_playing == TRUE)
+        return 0;
+
     if (buffersize != buffersize_new)
     {
         buffersize = buffersize_new;
@@ -243,8 +268,8 @@
 
     if (ice_tid)
     {
-	g_source_remove(ice_tid);
-	ice_tid = 0;
+        g_source_remove(ice_tid);
+        ice_tid = 0;
     }
 
     input.format = fmt;
@@ -267,49 +292,79 @@
 
         if (shout_set_host(shout, server_address) != SHOUTERR_SUCCESS)
         {
-            g_warning("Error setting hostname: %s\n", shout_get_error(shout));
+            g_warning(_("Error setting hostname: %s\n"), shout_get_error(shout));
             return 0;
         }
 
         if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS)
         {
-            g_warning("Error setting protocol: %s\n", shout_get_error(shout));
+            g_warning(_("Error setting protocol: %s\n"), shout_get_error(shout));
             return 0;
         }
 
         if (shout_set_port(shout, server_port) != SHOUTERR_SUCCESS)
         {
-            g_warning("Error setting port: %s\n", shout_get_error(shout));
+            g_warning(_("Error setting port: %s\n"), shout_get_error(shout));
             return 0;
         }
 
         if (shout_set_password(shout, server_password) != SHOUTERR_SUCCESS)
         {
-            g_warning("Error setting password: %s\n", shout_get_error(shout));
+            g_warning(_("Error setting password: %s\n"), shout_get_error(shout));
             return 0;
         }
 
         if (shout_set_mount(shout, mountpoint) != SHOUTERR_SUCCESS)
         {
-            g_warning("Error setting mount: %s\n", shout_get_error(shout));
+            g_warning(_("Error setting mount: %s\n"), shout_get_error(shout));
+            return 0;
+        }
+
+        if (shout_set_public(shout, stream_is_public) != SHOUTERR_SUCCESS)
+        {
+            g_warning(_("Error setting stream %s: %s\n"), stream_is_public?_("public"):_("private"), shout_get_error(shout));
+            return 0;
+        }
+
+        if (shout_set_name(shout, stream_name) != SHOUTERR_SUCCESS)
+        {
+            g_warning(_("Error setting stream name: %s\n"), shout_get_error(shout));
+            return 0;
+        }
+
+        if (shout_set_genre(shout, stream_genre) != SHOUTERR_SUCCESS)
+        {
+            g_warning(_("Error setting stream genre: %s\n"), shout_get_error(shout));
+            return 0;
+        }
+
+        if (shout_set_url(shout, stream_url) != SHOUTERR_SUCCESS)
+        {
+            g_warning(_("Error setting stream URL: %s\n"), shout_get_error(shout));
+            return 0;
+        }
+
+        if (shout_set_description(shout, stream_description) != SHOUTERR_SUCCESS)
+        {
+            g_warning(_("Error setting stream description: %s\n"), shout_get_error(shout));
             return 0;
         }
 
         if (shout_set_user(shout, server_user) != SHOUTERR_SUCCESS)
         {
-            g_warning("Error setting user: %s\n", shout_get_error(shout));
+            g_warning(_("Error setting user: %s\n"), shout_get_error(shout));
             return 0;
         }
 
         if (shout_set_format(shout, streamformat_shout[streamformat]) != SHOUTERR_SUCCESS)
         {
-            g_warning("Error setting user: %s\n", shout_get_error(shout));
+            g_warning(_("Error setting user: %s\n"), shout_get_error(shout));
             return 0;
         }
 
         if (shout_open(shout) != SHOUTERR_SUCCESS)
         {
-            g_warning("Error connecting to server: %s\n", shout_get_error(shout));
+            g_warning(_("Error connecting to server: %s\n"), shout_get_error(shout));
             return 0;
         }
     }
@@ -330,7 +385,7 @@
 
     rv = (plugin.open)();
 
-    g_debug("ICE_OPEN");
+    g_debug("ICE_OPEN[%d:%d:%d]", fmt, rate, nch);
     return rv;
 }
 
@@ -343,6 +398,26 @@
     plugin.write(convert_output, length);
 }
 
+static int ice_mod_samples(gpointer * d, gint length, AFormat afmt, gint srate, gint nch)
+{
+    if (ice_tid)
+        g_source_remove(ice_tid);
+
+    if (!shout)
+    {
+        ice_open(afmt, srate, nch);
+    }
+    if (shout)
+    {
+        int len;
+        ep_playing = TRUE;
+        len = convert_process(*d, length);
+        plugin.write(convert_output, length);
+        ice_tid = g_timeout_add_seconds(ice_close_timeout, ice_real_close, NULL);            
+    }
+    return length;
+}
+
 static gint ice_real_write(void* ptr, gint length)
 {
     gint ret;
@@ -356,21 +431,21 @@
 static gint ice_write_output(void *ptr, gint length)
 {
     if ((!shout) || (!length)) return 0;
-    g_debug("outputlength=%d, length=%d...", outputlength, length);
+    /*g_debug("outputlength=%d, length=%d...", outputlength, length);*/
     if ((outputlength > bufferflush) || ((outputlength+length) > buffersize))
     {
-        g_debug("flushing");
+        /*g_debug("flushing");*/
         outputlength = ice_real_write(outputbuffer, outputlength);
     }
     {
         if (length > buffersize)
         {
-            g_debug("data too long, flushing");
+            /*g_debug("data too long, flushing");*/
             ice_real_write(ptr, length);
         }
         else
         {
-            g_debug("adding");
+            /*g_debug("adding");*/
             memcpy(&(outputbuffer[outputlength]), ptr, length);
             outputlength += length;
         }
@@ -390,6 +465,7 @@
     }
     shout = NULL;
     ice_tid = 0;
+    ep_playing = FALSE;
     g_debug("ICE_REAL_CLOSE");
     return FALSE;
 }
@@ -399,7 +475,7 @@
 {
     if (ice_tid)
         g_source_remove(ice_tid);
-    ice_tid = g_timeout_add_seconds(3, ice_real_close, NULL);
+    ice_tid = g_timeout_add_seconds(ice_close_timeout, ice_real_close, NULL);
     g_debug("ICE_CLOSE: starting timer");
 }
 
@@ -466,6 +542,18 @@
     g_free(mountpoint);
     mountpoint = g_strdup(gtk_entry_get_text(GTK_ENTRY(mount_entry)));
 
+    g_free(stream_name);
+    stream_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(name_entry)));
+
+    g_free(stream_url);
+    stream_url = g_strdup(gtk_entry_get_text(GTK_ENTRY(url_entry)));
+
+    g_free(stream_genre);
+    stream_genre = g_strdup(gtk_entry_get_text(GTK_ENTRY(genre_entry)));
+
+    g_free(stream_description);
+    stream_description = g_strdup(gtk_entry_get_text(GTK_ENTRY(description_entry)));
+
     db = aud_cfg_db_open();
     aud_cfg_db_set_int(db, ICECAST_CFGID, "streamformat", streamformat);
     aud_cfg_db_set_string(db, ICECAST_CFGID, "server_address", server_address);
@@ -476,6 +564,11 @@
     aud_cfg_db_set_int(db, ICECAST_CFGID, "buffersize", buffersize_new);
     aud_cfg_db_set_double(db, ICECAST_CFGID, "bufferflush", bufferflushperc);
     aud_cfg_db_set_string(db, ICECAST_CFGID, "mountpoint", mountpoint);
+    aud_cfg_db_get_int(db, ICECAST_CFGID, "stream_is_public", &stream_is_public);
+    aud_cfg_db_set_string(db, ICECAST_CFGID, "stream_name", stream_name);
+    aud_cfg_db_set_string(db, ICECAST_CFGID, "stream_url", stream_url);
+    aud_cfg_db_set_string(db, ICECAST_CFGID, "stream_genre", stream_genre);
+    aud_cfg_db_set_string(db, ICECAST_CFGID, "stream_description", stream_description);
 
     aud_cfg_db_close(db);
 
@@ -560,15 +653,17 @@
 
         addr_entry = gtk_entry_new();
 
-	gtk_entry_set_text(GTK_ENTRY(addr_entry), server_address);
+        gtk_entry_set_text(GTK_ENTRY(addr_entry), server_address);
+        gtk_widget_set_tooltip_text(addr_entry, _("Server hostname or IP address"));
 
         gtk_box_pack_start(GTK_BOX(hbox), addr_entry, TRUE, TRUE, 0);
 
         port_spin = gtk_spin_button_new_with_range(0.0, 65535.0, 1.0);
+        gtk_widget_set_tooltip_text(port_spin, _("Server port number"));
 
         gtk_spin_button_set_digits(GTK_SPIN_BUTTON(port_spin), 0);
 
-	gtk_spin_button_set_value(GTK_SPIN_BUTTON(port_spin), (gdouble)server_port);
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(port_spin), (gdouble)server_port);
 
         gtk_box_pack_start(GTK_BOX(hbox), port_spin, TRUE, TRUE, 0);
 
@@ -582,7 +677,8 @@
 
         mount_entry = gtk_entry_new();
 
-	gtk_entry_set_text(GTK_ENTRY(mount_entry), mountpoint);
+        gtk_entry_set_text(GTK_ENTRY(mount_entry), mountpoint);
+        gtk_widget_set_tooltip_text(mount_entry, _("Mount point for the stream"));
 
         gtk_box_pack_start(GTK_BOX(hbox), mount_entry, TRUE, TRUE, 0);
 
@@ -596,7 +692,8 @@
 
         user_entry = gtk_entry_new();
 
-	gtk_entry_set_text(GTK_ENTRY(user_entry), server_user);
+        gtk_entry_set_text(GTK_ENTRY(user_entry), server_user);
+        gtk_widget_set_tooltip_text(user_entry, _("Icecast source user name for the stream; depends on your server settings.\nThe default value is \"source\""));
 
         gtk_box_pack_start(GTK_BOX(hbox), user_entry, TRUE, TRUE, 0);
 
@@ -604,8 +701,9 @@
         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
         password_entry = gtk_entry_new();
-
-	gtk_entry_set_text(GTK_ENTRY(password_entry), server_password);
+        
+        gtk_entry_set_text(GTK_ENTRY(password_entry), server_password);
+        gtk_widget_set_tooltip_text(password_entry, _("Icecast source user password"));
 
         gtk_entry_set_visibility(GTK_ENTRY(password_entry), FALSE);
 
@@ -620,10 +718,11 @@
         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
         timeout_spin = gtk_spin_button_new_with_range(1.0, 65535.0, 1.0);
+        gtk_widget_set_tooltip_text(timeout_spin, _("Amount of time before plugin closes connection to server when no audio data available"));
 
         gtk_spin_button_set_digits(GTK_SPIN_BUTTON(timeout_spin), 0);
 
-	gtk_spin_button_set_value(GTK_SPIN_BUTTON(timeout_spin), (gdouble)ice_close_timeout);
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(timeout_spin), (gdouble)ice_close_timeout);
 
         gtk_box_pack_start(GTK_BOX(hbox), timeout_spin, TRUE, TRUE, 0);
 
@@ -636,10 +735,11 @@
         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
         buffersize_spin = gtk_spin_button_new_with_range(1.0, 65535.0, 1.0);
+        gtk_widget_set_tooltip_text(buffersize_spin, _("Internal buffer size\nTry to increase this if you are experiencing audio skipping on client side"));
 
         gtk_spin_button_set_digits(GTK_SPIN_BUTTON(buffersize_spin), 0);
 
-	gtk_spin_button_set_value(GTK_SPIN_BUTTON(buffersize_spin), (gdouble)buffersize);
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(buffersize_spin), (gdouble)buffersize);
 
         gtk_box_pack_start(GTK_BOX(hbox), buffersize_spin, TRUE, TRUE, 0);
 
@@ -650,10 +750,11 @@
         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
         bufferflush_spin = gtk_spin_button_new_with_range(1.0, 65535.0, 1.0);
+        gtk_widget_set_tooltip_text(bufferflush_spin, _("Determines when to flush internal buffer to prevent its overflow"));
 
         gtk_spin_button_set_digits(GTK_SPIN_BUTTON(bufferflush_spin), 0);
 
-	gtk_spin_button_set_value(GTK_SPIN_BUTTON(bufferflush_spin), bufferflushperc);
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(bufferflush_spin), bufferflushperc);
 
         gtk_box_pack_start(GTK_BOX(hbox), bufferflush_spin, TRUE, TRUE, 0);
 
@@ -662,6 +763,68 @@
 
         gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
 
+        hbox = gtk_hbox_new(FALSE, 5);
+        gtk_box_pack_start(GTK_BOX(configure_vbox), hbox, FALSE, FALSE, 0);
+
+        public_check = gtk_check_button_new_with_label(_("Stream is public"));
+        gtk_widget_set_tooltip_text(public_check, _("Setting this asks the server to list the stream in any directories it knows about"));
+
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(public_check), stream_is_public?TRUE:FALSE);
+
+        gtk_box_pack_start(GTK_BOX(hbox), public_check, TRUE, TRUE, 0);
+
+        hbox = gtk_hbox_new(FALSE, 5);
+        gtk_box_pack_start(GTK_BOX(configure_vbox), hbox, FALSE, FALSE, 0);
+
+        label = gtk_label_new(_("Stream name:"));
+        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+        name_entry = gtk_entry_new();
+
+        gtk_entry_set_text(GTK_ENTRY(name_entry), stream_name);
+
+        gtk_box_pack_start(GTK_BOX(hbox), name_entry, TRUE, TRUE, 0);
+
+        hbox = gtk_hbox_new(FALSE, 5);
+        gtk_box_pack_start(GTK_BOX(configure_vbox), hbox, FALSE, FALSE, 0);
+
+        label = gtk_label_new(_("Stream URL:"));
+        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+        url_entry = gtk_entry_new();
+
+        gtk_entry_set_text(GTK_ENTRY(url_entry), stream_url);
+        gtk_widget_set_tooltip_text(url_entry, _("The URL of a site about this stream"));
+
+        gtk_box_pack_start(GTK_BOX(hbox), url_entry, TRUE, TRUE, 0);
+
+        hbox = gtk_hbox_new(FALSE, 5);
+        gtk_box_pack_start(GTK_BOX(configure_vbox), hbox, FALSE, FALSE, 0);
+
+        label = gtk_label_new(_("Stream genre:"));
+        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+        genre_entry = gtk_entry_new();
+
+        gtk_entry_set_text(GTK_ENTRY(genre_entry), stream_genre);
+        gtk_widget_set_tooltip_text(genre_entry, _("The genre (or genres) of the stream. This is usually a keyword list, eg \"pop rock rap\""));
+
+        gtk_box_pack_start(GTK_BOX(hbox), genre_entry, TRUE, TRUE, 0);
+
+        hbox = gtk_hbox_new(FALSE, 5);
+        gtk_box_pack_start(GTK_BOX(configure_vbox), hbox, FALSE, FALSE, 0);
+
+        label = gtk_label_new(_("Stream description:"));
+        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+        description_entry = gtk_entry_new();
+
+        gtk_entry_set_text(GTK_ENTRY(description_entry), stream_description);
+
+        gtk_box_pack_start(GTK_BOX(hbox), description_entry, TRUE, TRUE, 0);
+
+        gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
+
         configure_bbox = gtk_hbutton_box_new();
         gtk_button_box_set_layout(GTK_BUTTON_BOX(configure_bbox),
                                   GTK_BUTTONBOX_END);
--- a/src/scrobbler/gerpok.c	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/scrobbler/gerpok.c	Fri Aug 15 16:00:53 2008 +0200
@@ -5,9 +5,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-#include <curl/curl.h>
 #include <stdio.h>
 #include "fmt.h"
+#include "plugin.h"
 #include "scrobbler.h"
 #include "config.h"
 #include <glib.h>
@@ -416,6 +416,7 @@
 			SCROBBLER_CLI_ID, SCROBBLER_IMPLEMENTATION, gerpok_sc_username);
 
 	curl = curl_easy_init();
+        setup_proxy(curl);
 	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
 	curl_easy_setopt(curl, CURLOPT_URL, buf);
 	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 
@@ -621,6 +622,7 @@
         GString *submission;
 
 	curl = curl_easy_init();
+        setup_proxy(curl);
 	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
 	curl_easy_setopt(curl, CURLOPT_URL, gerpok_sc_submit_url);
 	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
--- a/src/scrobbler/plugin.c	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/scrobbler/plugin.c	Fri Aug 15 16:00:53 2008 +0200
@@ -19,6 +19,8 @@
 #include <wchar.h>
 #include <sys/time.h>
 
+#include <curl/curl.h>
+
 #include "plugin.h"
 #include "scrobbler.h"
 #include "gerpok.h"
@@ -338,6 +340,39 @@
 	return NULL;
 }
 
+void setup_proxy(CURL *curl)
+{
+    mcs_handle_t *db;
+    gboolean use_proxy;
+
+    db = aud_cfg_db_open();
+    aud_cfg_db_get_bool(db, NULL, "use_proxy", &use_proxy);
+    if (use_proxy == FALSE)
+    {
+        curl_easy_setopt(curl, CURLOPT_PROXY, "");
+    }
+    else
+    {
+        gchar *proxy_host, *proxy_port;
+        gboolean proxy_use_auth;
+        aud_cfg_db_get_string(db, NULL, "proxy_host", &proxy_host);
+        aud_cfg_db_get_string(db, NULL, "proxy_port", &proxy_port);
+        curl_easy_setopt(curl, CURLOPT_PROXY, proxy_host);
+        curl_easy_setopt(curl, CURLOPT_PROXYPORT, proxy_port);
+        aud_cfg_db_get_bool(db, NULL, "proxy_use_auth", &proxy_use_auth);
+        if (proxy_use_auth != FALSE)
+        {
+            gchar *userpwd, *user, *pass;
+            aud_cfg_db_get_string(db, NULL, "proxy_user", &user);
+            aud_cfg_db_get_string(db, NULL, "proxy_pass", &pass);
+            userpwd = g_strdup_printf("%s:%s", user, pass);
+            curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd);
+            g_free(userpwd);
+        }
+    }
+    aud_cfg_db_close(db);
+}
+
 GeneralPlugin *scrobbler_gplist[] = { &scrobbler_gp, NULL };
 
 DECLARE_PLUGIN(scrobbler, NULL, NULL, NULL, NULL, NULL, scrobbler_gplist, NULL, NULL);
--- a/src/scrobbler/plugin.h	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/scrobbler/plugin.h	Fri Aug 15 16:00:53 2008 +0200
@@ -1,7 +1,10 @@
 #ifndef PLUGIN_H
 #define PLUGIN_H
 
+#include <curl/curl.h>
+
 void start(void);
 void stop(void);
+void setup_proxy(CURL *curl);
 
 #endif
--- a/src/scrobbler/scrobbler.c	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/scrobbler/scrobbler.c	Fri Aug 15 16:00:53 2008 +0200
@@ -3,9 +3,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-#include <curl/curl.h>
 #include <stdio.h>
 #include "fmt.h"
+#include "plugin.h"
 #include "scrobbler.h"
 #include "config.h"
 #include "settings.h"
@@ -489,6 +489,7 @@
     g_free(auth_tmp);
 
     curl = curl_easy_init();
+    setup_proxy(curl);
     curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
     curl_easy_setopt(curl, CURLOPT_URL, buf);
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 
@@ -704,6 +705,7 @@
     gchar *entry;
 
     curl = curl_easy_init();
+    setup_proxy(curl);
     curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
     curl_easy_setopt(curl, CURLOPT_URL, sc_np_url);
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
@@ -763,6 +765,7 @@
         GString *submission;
 
     curl = curl_easy_init();
+    setup_proxy(curl);
     curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
     curl_easy_setopt(curl, CURLOPT_URL, sc_submit_url);
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
--- a/src/skins/plugin.c	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/skins/plugin.c	Fri Aug 15 16:00:53 2008 +0200
@@ -88,6 +88,10 @@
     init_skins(config.skin);
     mainwin_setup_menus();
 
+    gint h_vol[2];
+    aud_input_get_volume(&h_vol[0], &h_vol[1]);
+    aud_hook_call("volume set", h_vol);
+
     skins_interface.ops->create_prefs_window();
     cfgdlg = skins_configure();
     aud_prefswin_page_new(cfgdlg, N_("Skinned Interface"), DATA_DIR "/images/appearance.png");
--- a/src/streambrowser/xiph.c	Fri Aug 15 16:00:43 2008 +0200
+++ b/src/streambrowser/xiph.c	Fri Aug 15 16:00:53 2008 +0200
@@ -66,13 +66,13 @@
 };
 
 
-static void refresh_streamdir();
+static void refresh_streamdir(void);
 	/* 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;
+	gint entryno;
 	
 	refresh_streamdir();
 	
@@ -94,8 +94,8 @@
 {
 	refresh_streamdir();
 
-	int entryno, categoryno;
-	int xiph_category_count = sizeof(xiph_categories) / sizeof(xiph_category_t);
+	gint entryno, categoryno;
+	gint xiph_category_count = sizeof(xiph_categories) / sizeof(xiph_category_t);
 	xiph_category_t *xiph_category = NULL;
 	
 	for (categoryno = 0; categoryno < xiph_category_count; categoryno++)
@@ -145,10 +145,10 @@
 }
 
 
-streamdir_t* xiph_streamdir_fetch()
+streamdir_t* xiph_streamdir_fetch(void)
 {
 	streamdir_t *streamdir = streamdir_new(XIPH_NAME);
-	int categno;
+	gint categno;
 	
 	refresh_streamdir();
 	
@@ -160,7 +160,7 @@
 	return streamdir;
 }
 
-static void refresh_streamdir()
+static void refresh_streamdir(void)
 {
 	/* free any previously fetched streamdir data */
 	if (xiph_entries != NULL) {
@@ -226,21 +226,16 @@
 
 static gboolean genre_match(gchar *string1, gchar *string2)
 {
-	char *saveptr = NULL;
-	char *token;
+	gchar *saveptr = NULL, *token;
 	gboolean matched = FALSE;
-	char temp1[strlen(string1) + 1];
-	char temp2[strlen(string2) + 1];
+	gchar *temp1 = g_strdup(string1),
+		*temp2 = g_strdup(string2);
 
-	/* these are required for strtok_r to work properly */	
-	strcpy(temp1, string1);
-	strcpy(temp2, string2);
-	
 	token = strtok_r(temp1, " ", &saveptr);
 	while (token != NULL) {
 		if (mystrcasestr(temp2, token))
 			matched = TRUE;
-			
+		
 		token = strtok_r(NULL, " ", &saveptr);
 	}