changeset 1731:38375d565192

branch merge
author Ralf Ertzinger <ralf@skytale.net>
date Tue, 18 Sep 2007 18:03:11 +0200
parents 50d151b259bb (current diff) 63feceeb3799 (diff)
children 4bdb8621853e f0b53c4db5ba 8feacd004f50
files
diffstat 8 files changed, 428 insertions(+), 235 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Tue Sep 18 18:01:00 2007 +0200
+++ b/configure.ac	Tue Sep 18 18:03:11 2007 +0200
@@ -447,6 +447,27 @@
     GENERAL_PLUGINS="$GENERAL_PLUGINS hotkey"
 fi
 
+dnl *** Gnome Shortcuts Plugin
+
+AC_ARG_ENABLE(gnomeshortcuts,
+    [  --disable-gnomeshortcuts        disable gnome shortcuts (default=enabled)],
+    [enable_gnomeshortcuts=$enableval],
+    [enable_gnomeshortcuts="yes"]
+)
+
+if test "x$enable_gnomeshortcuts" = "xyes"; then
+    have_gnomeshortcuts="yes"
+    PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.60 dbus-glib-1 >= 0.60],,
+         [AC_MSG_ERROR([Cannot find dbus-glib >= 0.60 for gnomeshortcuts plugin])])
+else
+    AC_MSG_RESULT([*** Gnome Shortcuts Plugin disabled per user request ***])
+    have_gnomeshortcuts="no"
+fi
+
+if test "x$have_gnomeshortcuts" = "xyes"; then
+    GENERAL_PLUGINS="$GENERAL_PLUGINS gnomeshortcuts"
+fi
+
 dnl *** Status Icon plugin (for X11 only)
 
 AC_ARG_ENABLE(statusicon,
@@ -1581,6 +1602,7 @@
 echo "    -> X Composite support:               $have_aosd_xcomp"
 echo "  Control via event device (evdev-plug):  $have_evdevplug"
 echo "  Global Hotkey Plugin:                   $have_hotkey"
+echo "  Gnome Shortcuts Plugin:                 $have_gnomeshortcuts"
 echo "  LIRC:                                   $have_lirc"
 echo "  AudioScrobbler Client:                  $scrobbler"
 echo "  Upload to MTP device:                   $have_mtp_up"
--- a/src/alsa/alsa.h	Tue Sep 18 18:01:00 2007 +0200
+++ b/src/alsa/alsa.h	Tue Sep 18 18:03:11 2007 +0200
@@ -56,7 +56,6 @@
 	{
 		int left, right;
 	} vol;
-	gboolean soft_volume;
 };
 
 extern struct alsa_config alsa_cfg;
--- a/src/alsa/audio.c	Tue Sep 18 18:01:00 2007 +0200
+++ b/src/alsa/audio.c	Tue Sep 18 18:03:11 2007 +0200
@@ -4,6 +4,7 @@
  *                           Thomas Nilsson and 4Front Technologies
  *  Copyright (C) 1999-2006  Haavard Kvaalen
  *  Copyright (C) 2005       Takashi Iwai
+ *  Copyright (C) 2007       William Pitcock
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -132,8 +133,12 @@
 	return snd_pcm_state(alsa_pcm) == SND_PCM_STATE_RUNNING;
 }
 
-static int xrun_recover(void)
+static int
+alsa_recovery(int err)
 {
+	int err2;
+
+	/* if debug mode is enabled, dump ALSA state to console */
 	if (alsa_cfg.debug)
 	{
 		snd_pcm_status_t *alsa_status;
@@ -146,37 +151,33 @@
 			snd_pcm_status_dump(alsa_status, logs);
 		}
 	}
-	return snd_pcm_prepare(alsa_pcm);
-}
 
-static int suspend_recover(void)
-{
-	int err;
-
-	while ((err = snd_pcm_resume(alsa_pcm)) == -EAGAIN)
-		/* wait until suspend flag is released */
-		g_usleep(1000000);
-	if (err < 0)
-	{
-		g_warning("alsa_handle_error(): "
-			  "snd_pcm_resume() failed.");
-		return snd_pcm_prepare(alsa_pcm);
-	}
-	return err;
-}
-
-/* handle generic errors */
-static int alsa_handle_error(int err)
-{
+	/*
+	 * specifically handle -EPIPE and -ESTRPIPE to recover 
+	 * PCM fragment periods without losing data.
+	 */
 	switch (err)
 	{
-		case -EPIPE:
-			return xrun_recover();
-		case -ESTRPIPE:
-			return suspend_recover();
+	case -ESTRPIPE:   /* "suspend": wait until ALSA is "running" again. */
+		while ((err2 = snd_pcm_resume(alsa_pcm)) == -EAGAIN)
+			g_usleep(100000);
+
+		if (err2 < 0)
+			return snd_pcm_prepare(alsa_pcm);
+
+		break;
+
+	case -EPIPE:      /* under-run and the I/O pipe closed on us */
+		return snd_pcm_prepare(alsa_pcm);
+		break;
+
+	default:
+		g_warning("Unhandled ALSA exception code %d (%s), trying hard restart.", err, snd_strerror(err));
+		return snd_pcm_prepare(alsa_pcm);
+		break;
 	}
 
-	return err;
+	return 0;
 }
 
 /* update and get the available space on h/w buffer (in frames) */
@@ -189,11 +190,11 @@
 
 	while ((ret = snd_pcm_avail_update(alsa_pcm)) < 0)
 	{
-		ret = alsa_handle_error(ret);
+		ret = alsa_recovery(ret);
 		if (ret < 0)
 		{
 			g_warning("alsa_get_avail(): snd_pcm_avail_update() failed: %s",
-				  snd_strerror(-ret));
+				  snd_strerror(ret));
 			return 0;
 		}
 	}
@@ -248,7 +249,7 @@
 		snd_pcm_drop(alsa_pcm);
 		if ((err = snd_pcm_close(alsa_pcm)) < 0)
 			g_warning("alsa_pcm_close() failed: %s",
-				  snd_strerror(-err));
+				  snd_strerror(err));
 		alsa_pcm = NULL;
 	}
 }
@@ -349,7 +350,7 @@
 	if ((err = snd_mixer_open(mixer, 0)) < 0)
 	{
 		g_warning("alsa_get_mixer(): Failed to open empty mixer: %s",
-			  snd_strerror(-err));
+			  snd_strerror(err));
 		mixer = NULL;
 		return -1;
 	}
@@ -358,7 +359,7 @@
 	if ((err = snd_mixer_attach(*mixer, dev)) < 0)
 	{
 		g_warning("alsa_get_mixer(): Attaching to mixer %s failed: %s",
-			  dev, snd_strerror(-err));
+			  dev, snd_strerror(err));
 		g_free(dev);
 		return -1;
 	}
@@ -367,13 +368,13 @@
 	if ((err = snd_mixer_selem_register(*mixer, NULL, NULL)) < 0)
 	{
 		g_warning("alsa_get_mixer(): Failed to register mixer: %s",
-			  snd_strerror(-err));
+			  snd_strerror(err));
 		return -1;
 	}
 	if ((err = snd_mixer_load(*mixer)) < 0)
 	{
 		g_warning("alsa_get_mixer(): Failed to load mixer: %s",
-			  snd_strerror(-err));
+			  snd_strerror(err));
 		return -1;
 	}
 
@@ -442,8 +443,7 @@
 		return -1;
 	}
 
-	if (!alsa_cfg.soft_volume)
-		alsa_set_volume(a * 100 / alsa_max_vol, b * 100 / alsa_max_vol);
+	alsa_set_volume(a * 100 / alsa_max_vol, b * 100 / alsa_max_vol);
 
 	debug("alsa_setup_mixer: end");
 
@@ -484,28 +484,20 @@
 		mixer_start = FALSE;
 	}
 
-	if (alsa_cfg.soft_volume)
-	{
-		*l = alsa_cfg.vol.left;
-		*r = alsa_cfg.vol.right;
-	}
-
 	if (!pcm_element)
 		return;
 
 	snd_mixer_handle_events(mixer);
 
-	if (!alsa_cfg.soft_volume)
-	{
-		snd_mixer_selem_get_playback_volume(pcm_element,
-						    SND_MIXER_SCHN_FRONT_LEFT,
-						    &ll);
-		snd_mixer_selem_get_playback_volume(pcm_element,
-						    SND_MIXER_SCHN_FRONT_RIGHT,
-						    &lr);
-		*l = ll;
-		*r = lr;
-	}
+	snd_mixer_selem_get_playback_volume(pcm_element,
+					    SND_MIXER_SCHN_FRONT_LEFT,
+					    &ll);
+	snd_mixer_selem_get_playback_volume(pcm_element,
+					    SND_MIXER_SCHN_FRONT_RIGHT,
+					    &lr);
+	*l = ll;
+	*r = lr;
+
 	if (mixer_timeout)
 		gtk_timeout_remove(mixer_timeout);
 	mixer_timeout = gtk_timeout_add(5000, alsa_mixer_timeout, NULL);
@@ -514,13 +506,6 @@
 
 void alsa_set_volume(int l, int r)
 {
-	if (alsa_cfg.soft_volume)
-	{
-		alsa_cfg.vol.left = l;
-		alsa_cfg.vol.right = r;
-		return;
-	}
-
 	if (!pcm_element)
 		return;
 
@@ -589,110 +574,6 @@
 	return (alsa_total_written * 1000) / inputf->bps;
 }
 
-#define STEREO_ADJUST(type, type2, endian)					\
-do {										\
-	type *ptr = data;							\
-	for (i = 0; i < length; i += 4)						\
-	{									\
-		*ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) *	\
-					   lvol / 256);				\
-		ptr++;								\
-		*ptr = type2##_TO_##endian(type2##_FROM_##endian(*ptr) *	\
-					   rvol / 256);				\
-		ptr++;								\
-	}									\
-} while (0)
-
-#define MONO_ADJUST(type, type2, endian)					\
-do {										\
-	type *ptr = data;							\
-	for (i = 0; i < length; i += 2)						\
-	{									\
-		*ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) *	\
-					   vol / 256);				\
-		ptr++;								\
-	}									\
-} while (0)
-
-#define VOLUME_ADJUST(type, type2, endian)		\
-do {							\
-	if (channels == 2)				\
-		STEREO_ADJUST(type, type2, endian);	\
-	else						\
-		MONO_ADJUST(type, type2, endian);	\
-} while (0)
-
-#define STEREO_ADJUST8(type)				\
-do {							\
-	type *ptr = data;				\
-	for (i = 0; i < length; i += 2)			\
-	{						\
-		*ptr = *ptr * lvol / 256;		\
-		ptr++;					\
-		*ptr = *ptr * rvol / 256;		\
-		ptr++;					\
-	}						\
-} while (0)
-
-#define MONO_ADJUST8(type)			\
-do {						\
-	type *ptr = data;			\
-	for (i = 0; i < length; i++)		\
-	{					\
-		*ptr = *ptr * vol / 256;	\
-		ptr++;				\
-	}					\
-} while (0)
-
-#define VOLUME_ADJUST8(type)			\
-do {						\
-	if (channels == 2)			\
-		STEREO_ADJUST8(type);		\
-	else					\
-		MONO_ADJUST8(type);		\
-} while (0)
-
-
-static void volume_adjust(void* data, int length, AFormat fmt, int channels)
-{
-	int i, vol, lvol, rvol;
-
-	if ((alsa_cfg.vol.left == 100 && alsa_cfg.vol.right == 100) ||
-	    (channels == 1 &&
-	     (alsa_cfg.vol.left == 100 || alsa_cfg.vol.right == 100)))
-		return;
-
-	lvol = pow(10, (alsa_cfg.vol.left - 100) / 40.0) * 256;
-	rvol = pow(10, (alsa_cfg.vol.right - 100) / 40.0) * 256;
-	vol = MAX(lvol, rvol);
-
-	switch (fmt)
-	{
-		case FMT_S16_LE:
-			VOLUME_ADJUST(gint16, GINT16, LE);
-			break;
-		case FMT_U16_LE:
-			VOLUME_ADJUST(guint16, GUINT16, LE);
-			break;
-		case FMT_S16_BE:
-			VOLUME_ADJUST(gint16, GINT16, BE);
-			break;
-		case FMT_U16_BE:
-			VOLUME_ADJUST(guint16, GUINT16, BE);
-			break;
-		case FMT_S8:
-			VOLUME_ADJUST8(gint8);
-			break;
-		case FMT_U8:
-			VOLUME_ADJUST8(guint8);
-			break;
-		default:
-			g_warning("volue_adjust(): unhandled format: %d", fmt);
-			break;
-	}
-}
-
-
 /* transfer data to audio h/w; length is given in bytes
  *
  * data can be modified via effect plugin, rate conversion or
@@ -717,9 +598,6 @@
 						     effectf->rate,
 						     outputf->rate);
 
-	if (alsa_cfg.soft_volume)
-		volume_adjust(data, length, outputf->xmms_format, outputf->channels);
-
 	alsa_write_audio(data, length);
 }
 
@@ -764,11 +642,11 @@
 		}
 		else
 		{
-			int err = alsa_handle_error((int)written_frames);
+			int err = alsa_recovery((int)written_frames);
 			if (err < 0)
 			{
 				g_warning("alsa_write_audio(): write error: %s",
-					  snd_strerror(-err));
+					  snd_strerror(err));
 				break;
 			}
 		}
@@ -820,7 +698,7 @@
 			}
 			else if (wr < 0)
 			{
-				alsa_handle_error(wr);
+				alsa_recovery(wr);
 			}
 		}
 		else
@@ -963,7 +841,7 @@
 				SND_PCM_NONBLOCK)) < 0)
 	{
 		g_warning("alsa_setup(): Failed to open pcm device (%s): %s",
-			  alsa_cfg.pcm_device, snd_strerror(-err));
+			  alsa_cfg.pcm_device, snd_strerror(err));
 		alsa_pcm = NULL;
 		g_free(outputf);
 		outputf = NULL;
@@ -992,7 +870,7 @@
 	if ((err = snd_pcm_hw_params_any(alsa_pcm, hwparams)) < 0)
 	{
 		g_warning("alsa_setup(): No configuration available for "
-			  "playback: %s", snd_strerror(-err));
+			  "playback: %s", snd_strerror(err));
 		return -1;
 	}
 
@@ -1000,7 +878,7 @@
 						SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
 	{
 		g_warning("alsa_setup(): Cannot set direct write mode: %s",
-			  snd_strerror(-err));
+			  snd_strerror(err));
 		return -1;
 	}
 
@@ -1040,7 +918,7 @@
 		{
 			g_warning("alsa_setup(): Sample format not "
 				  "available for playback: %s",
-				  snd_strerror(-err));
+				  snd_strerror(err));
 			return -1;
 		}
 	}
@@ -1083,7 +961,7 @@
 							  &alsa_buffer_time, 0)) < 0)
 	{
 		g_warning("alsa_setup(): Set buffer time failed: %s.",
-			  snd_strerror(-err));
+			  snd_strerror(err));
 		return -1;
 	}
 
@@ -1092,7 +970,7 @@
 							  &alsa_period_time, 0)) < 0)
 	{
 		g_warning("alsa_setup(): Set period time failed: %s.",
-			  snd_strerror(-err));
+			  snd_strerror(err));
 		return -1;
 	}
 
@@ -1108,7 +986,7 @@
 	{
 		g_warning("alsa_setup(): snd_pcm_hw_params_get_buffer_size() "
 			  "failed: %s",
-			  snd_strerror(-err));
+			  snd_strerror(err));
 		return -1;
 	}
 
@@ -1116,7 +994,7 @@
 	{
 		g_warning("alsa_setup(): snd_pcm_hw_params_get_period_size() "
 			  "failed: %s",
-			  snd_strerror(-err));
+			  snd_strerror(err));
 		return -1;
 	}
 
@@ -1129,7 +1007,7 @@
 	if ((err = snd_pcm_sw_params_set_start_threshold(alsa_pcm,
 			swparams, alsa_buffer_size - alsa_period_size) < 0))
 		g_warning("alsa_setup(): setting start "
-			  "threshold failed: %s", snd_strerror(-err));
+			  "threshold failed: %s", snd_strerror(err));
 	if (snd_pcm_sw_params(alsa_pcm, swparams) < 0)
 	{
 		g_warning("alsa_setup(): Unable to install sw params");
--- a/src/alsa/configure.c	Tue Sep 18 18:01:00 2007 +0200
+++ b/src/alsa/configure.c	Tue Sep 18 18:03:11 2007 +0200
@@ -21,7 +21,6 @@
 
 static GtkWidget *configure_win = NULL;
 static GtkWidget *buffer_time_spin, *period_time_spin;
-static GtkWidget *softvolume_toggle_button;
 
 static GtkWidget *devices_combo, *mixer_devices_combo;
 
@@ -38,7 +37,6 @@
 	alsa_cfg.pcm_device = GET_CHARS(GTK_COMBO(devices_combo)->entry);
 	alsa_cfg.buffer_time = GET_SPIN_INT(buffer_time_spin);
 	alsa_cfg.period_time = GET_SPIN_INT(period_time_spin);
-	alsa_cfg.soft_volume = GET_TOGGLE(softvolume_toggle_button);
 	alsa_cfg.mixer_card = current_mixer_card;
 	alsa_cfg.mixer_device = GET_CHARS(GTK_COMBO(mixer_devices_combo)->entry);
 
@@ -55,8 +53,6 @@
 	bmp_cfg_db_set_string(cfgfile,"ALSA","pcm_device", alsa_cfg.pcm_device);
 	bmp_cfg_db_set_int(cfgfile, "ALSA", "mixer_card", alsa_cfg.mixer_card);
 	bmp_cfg_db_set_string(cfgfile,"ALSA","mixer_device", alsa_cfg.mixer_device);
-	bmp_cfg_db_set_bool(cfgfile, "ALSA", "soft_volume",
-			       alsa_cfg.soft_volume);
 	bmp_cfg_db_set_int(cfgfile, "ALSA", "volume_left", alsa_cfg.vol.left);
 	bmp_cfg_db_set_int(cfgfile, "ALSA", "volume_right", alsa_cfg.vol.right);
 	bmp_cfg_db_close(cfgfile);
@@ -69,7 +65,7 @@
 
 	menu = gtk_menu_new();
 	if ((err = snd_card_next(&card)) != 0)
-		g_warning("snd_next_card() failed: %s", snd_strerror(-err));
+		g_warning("snd_next_card() failed: %s", snd_strerror(err));
 
 	while (card > -1)
 	{
@@ -81,7 +77,7 @@
 		if ((err = snd_card_get_name(card, &label)) != 0)
 		{
 			g_warning("snd_carg_get_name() failed: %s",
-				  snd_strerror(-err));
+				  snd_strerror(err));
 			break;
 		}
 
@@ -93,7 +89,7 @@
 		if ((err = snd_card_next(&card)) != 0)
 		{
 			g_warning("snd_next_card() failed: %s",
-				  snd_strerror(-err));
+				  snd_strerror(err));
 			break;
 		}
 	}
@@ -140,13 +136,13 @@
 
 	if ((err = snd_ctl_open(&ctl, dev, 0)) < 0)
 	{
-		printf("snd_ctl_open() failed: %s", snd_strerror(-err));
+		printf("snd_ctl_open() failed: %s", snd_strerror(err));
 		return;
 	}
 
 	if ((err = snd_card_get_name(card, &card_name)) != 0)
 	{
-		g_warning("snd_card_get_name() failed: %s", snd_strerror(-err));
+		g_warning("snd_card_get_name() failed: %s", snd_strerror(err));
 		card_name = _("Unknown soundcard");
 	}
 
@@ -158,7 +154,7 @@
 		if ((err = snd_ctl_pcm_next_device(ctl, &pcm_device)) < 0)
 		{
 			g_warning("snd_ctl_pcm_next_device() failed: %s",
-				  snd_strerror(-err));
+				  snd_strerror(err));
 			pcm_device = -1;
 		}
 		if (pcm_device < 0)
@@ -174,7 +170,7 @@
 				g_warning("get_devices_for_card(): "
 					  "snd_ctl_pcm_info() "
 					  "failed (%d:%d): %s.", card,
-					  pcm_device, snd_strerror(-err));
+					  pcm_device, snd_strerror(err));
 			continue;
 		}
 
@@ -211,7 +207,7 @@
 
 	if ((err = snd_card_next(&card)) != 0)
 	{
-		g_warning("snd_next_card() failed: %s", snd_strerror(-err));
+		g_warning("snd_next_card() failed: %s", snd_strerror(err));
 		return;
 	}
 
@@ -221,7 +217,7 @@
 		if ((err = snd_card_next(&card)) != 0)
 		{
 			g_warning("snd_next_card() failed: %s",
-				  snd_strerror(-err));
+				  snd_strerror(err));
 			break;
 		}
 	}
@@ -236,13 +232,6 @@
 			  current_mixer_card);
 }
 
-static void softvolume_toggle_cb(GtkToggleButton * widget, gpointer data)
-{
-	gboolean softvolume = gtk_toggle_button_get_active(widget);
-	gtk_widget_set_sensitive(GTK_WIDGET(data), !softvolume);
-	gtk_widget_set_sensitive(mixer_devices_combo, !softvolume);
-}
-
 void alsa_configure(void)
 {
 	GtkWidget *vbox, *notebook;
@@ -303,12 +292,6 @@
 	gtk_container_set_border_width(GTK_CONTAINER(mixer_box), 5);
 	gtk_container_add(GTK_CONTAINER(mixer_frame), mixer_box);
 
-	softvolume_toggle_button = gtk_check_button_new_with_label(
-		_("Use software volume control"));
-
-	gtk_box_pack_start(GTK_BOX(mixer_box), softvolume_toggle_button,
-			   FALSE, FALSE, 0);
-
 	mixer_table = gtk_table_new(2, 2, FALSE);
 	gtk_table_set_row_spacings(GTK_TABLE(mixer_table), 5);
 	gtk_table_set_col_spacings(GTK_TABLE(mixer_table), 5);
@@ -341,11 +324,6 @@
 	gtk_table_attach(GTK_TABLE(mixer_table), mixer_devices_combo,
 			 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
 
-	gtk_signal_connect(GTK_OBJECT(softvolume_toggle_button), "toggled",
-			   (GCallback)softvolume_toggle_cb, mixer_card_om);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(softvolume_toggle_button),
-				     alsa_cfg.soft_volume);
-
 	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dev_vbox,
 				 gtk_label_new(_("Device settings")));
 
--- a/src/alsa/init.c	Tue Sep 18 18:01:00 2007 +0200
+++ b/src/alsa/init.c	Tue Sep 18 18:03:11 2007 +0200
@@ -47,11 +47,6 @@
 	bmp_cfg_db_get_int(cfgfile, "ALSA", "buffer_time", &alsa_cfg.buffer_time);
 	bmp_cfg_db_get_int(cfgfile, "ALSA", "period_time", &alsa_cfg.period_time);
 
-	bmp_cfg_db_get_bool(cfgfile, "ALSA", "soft_volume",
-			      &alsa_cfg.soft_volume);
-	bmp_cfg_db_get_int(cfgfile, "ALSA", "volume_left", &alsa_cfg.vol.left);
-	bmp_cfg_db_get_int(cfgfile, "ALSA", "volume_right", &alsa_cfg.vol.right);
-
 	bmp_cfg_db_get_bool(cfgfile, "ALSA", "debug", &alsa_cfg.debug);
 	bmp_cfg_db_close(cfgfile);
 
--- a/src/arts/arts.c	Tue Sep 18 18:01:00 2007 +0200
+++ b/src/arts/arts.c	Tue Sep 18 18:03:11 2007 +0200
@@ -32,25 +32,23 @@
 
 OutputPlugin arts_op =
 {
-	NULL,
-	NULL,
-	"aRts Output Plugin",
-	artsxmms_init,
-	NULL,
-	about,
-	artsxmms_configure,
-	artsxmms_get_volume,
-	artsxmms_set_volume,
-	artsxmms_open,
-	artsxmms_write,
-	artsxmms_close,
-	artsxmms_flush,
-	artsxmms_pause,
-	artsxmms_free,
-	artsxmms_playing,
-	artsxmms_get_output_time,
-	artsxmms_get_written_time,
-	artsxmms_tell_audio
+	.description = "aRts Output Plugin",
+	.init = artsxmms_init,
+	.cleanup = NULL,
+	.about = about,
+	.configure = artsxmms_configure,
+	.get_volume = artsxmms_get_volume,
+	.set_volume = artsxmms_set_volume,
+	.open_audio = artsxmms_open,
+	.write_audio = artsxmms_write,
+	.close_audio = artsxmms_close,
+	.flush = artsxmms_flush,
+	.pause = artsxmms_pause,
+	.buffer_free = artsxmms_free,
+	.buffer_playing = artsxmms_playing,
+	.output_time = artsxmms_get_output_time,
+	.written_time = artsxmms_get_written_time,
+	.tell_audio = artsxmms_tell_audio
 };
 
 OutputPlugin *arts_oplist[] = { &arts_op, NULL };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gnomeshortcuts/Makefile	Tue Sep 18 18:03:11 2007 +0200
@@ -0,0 +1,16 @@
+include ../../mk/rules.mk
+include ../../mk/init.mk
+
+OBJECTIVE_LIBS = libgnomeshortcuts$(SHARED_SUFFIX)
+
+LIBDIR = $(plugindir)/$(GENERAL_PLUGIN_DIR)
+
+LIBADD = $(GLIB_LIBS) $(DBUS_LIBS)
+SOURCES = gnomeshortcuts.c
+
+OBJECTS = ${SOURCES:.c=.o}
+
+CFLAGS += $(PICFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) \
+	-I../../intl -I../.. -I..
+
+include ../../mk/objective.mk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gnomeshortcuts/gnomeshortcuts.c	Tue Sep 18 18:03:11 2007 +0200
@@ -0,0 +1,307 @@
+/* -*- Mode: C; indent-tabs: t; c-basic-offset: 9; tab-width: 9 -*- */
+/*
+ *  This file is part of audacious-gnome-shortcut plugin for audacious
+ *
+ *  Copyright (c) 2007        Sascha Hlusiak <contact@saschahlusiak.de>
+ *  Name: plugin.c
+ *  Description: plugin.c
+ * 
+ *  audacious-gnome-shortcut is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  audacious-gnome-shortcut is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with audacious-gnome-shortcut; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <glib-object.h>
+
+#include <audacious/plugin.h>
+#include <audacious/auddrct.h>
+
+#include <audacious/i18n.h>
+#include <audacious/util.h>
+
+
+static void init (void);
+static void about (void);
+static void cleanup (void);
+void gnome_remote_init();
+void gnome_remote_uninit();
+
+static gboolean loaded = FALSE;
+static DBusGProxy *media_player_keys_proxy = NULL;
+
+static GeneralPlugin audaciousgnomeshortcuts =
+{
+	.description = "Gnome Shortcuts",
+	.init = init,
+	.about = about,
+	.cleanup = cleanup
+};
+
+GeneralPlugin *gnomeshortcuts_gplist[] = { &audaciousgnomeshortcuts, NULL };
+SIMPLE_GENERAL_PLUGIN(gnomeshortcuts, gnomeshortcuts_gplist);
+
+#define g_marshal_value_peek_string(v)   (char*) g_value_get_string (v)
+
+
+static void
+hotkey_marshal_VOID__STRING_STRING (GClosure     *closure,
+                                   GValue       *return_value,
+                                   guint         n_param_values,
+                                   const GValue *param_values,
+                                   gpointer      invocation_hint,
+                                   gpointer      marshal_data)
+{
+	typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer     data1,
+							gpointer     arg_1,
+							gpointer     arg_2);
+	register GMarshalFunc_VOID__STRING_STRING callback;
+	register GCClosure *cc = (GCClosure*) closure;
+	register gpointer data1;
+	
+	g_return_if_fail (n_param_values == 3);
+	
+	if (G_CCLOSURE_SWAP_DATA (closure))
+	{
+		data1 = closure->data;
+	} else {
+		data1 = g_value_peek_pointer (param_values + 0);
+	}
+	callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
+	
+	callback (data1,
+		g_marshal_value_peek_string (param_values + 1),
+		g_marshal_value_peek_string (param_values + 2));
+}
+
+static void
+on_media_player_key_pressed (DBusGProxy *proxy, const gchar *application, const gchar *key)
+{
+	if (strcmp ("Audacious", application) == 0) {
+		gint current_volume, old_volume;
+		static gint volume_static = 0;
+		gboolean play, mute;
+		
+		/* playing or not */
+		play = audacious_drct_is_playing ();
+		
+		/* get current volume */
+		audacious_drct_get_volume_main (&current_volume);
+		old_volume = current_volume;
+		if (current_volume)
+		{
+			/* volume is not mute */
+			mute = FALSE;
+		} else {
+			/* volume is mute */
+			mute = TRUE;
+		}
+			
+		/* mute the playback */
+		if (strcmp ("Mute", key) == 0)
+		{
+			if (!mute)
+			{
+				volume_static = current_volume;
+				audacious_drct_set_main_volume (0);
+				mute = TRUE;
+			} else {
+				audacious_drct_set_main_volume (volume_static);
+				mute = FALSE;
+			}
+			return;
+		}
+		
+		/* decreace volume */
+/*		if ((keycode == plugin_cfg.vol_down) && (state == plugin_cfg.vol_down_mask))
+		{
+			if (mute)
+			{
+				current_volume = old_volume;
+				old_volume = 0;
+				mute = FALSE;
+			}
+				
+			if ((current_volume -= plugin_cfg.vol_decrement) < 0)
+			{
+				current_volume = 0;
+			}
+				
+			if (current_volume != old_volume)
+			{
+				xmms_remote_set_main_volume (audacioushotkey.xmms_session,
+							current_volume);
+			}
+				
+			old_volume = current_volume;
+			return TRUE;
+		}*/
+		
+		/* increase volume */
+/*		if ((keycode == plugin_cfg.vol_up) && (state == plugin_cfg.vol_up_mask))
+		{
+			if (mute)
+			{
+				current_volume = old_volume;
+				old_volume = 0;
+				mute = FALSE;
+			}
+				
+			if ((current_volume += plugin_cfg.vol_increment) > 100)
+			{
+				current_volume = 100;
+			}
+				
+			if (current_volume != old_volume)
+			{
+				xmms_remote_set_main_volume (audacioushotkey.xmms_session,
+							current_volume);
+			}
+				
+			old_volume = current_volume;
+			return TRUE;
+		}*/
+		
+		/* play */
+		if (strcmp ("Play", key) == 0)
+		{
+			if (!play)
+			{
+				audacious_drct_play ();
+			} else {
+				audacious_drct_pause ();
+			}
+			return;
+		}
+	
+		/* pause */
+		if (strcmp ("Pause", key) == 0)
+		{
+			if (!play) audacious_drct_play ();
+			else audacious_drct_pause ();
+	
+			return;
+		}
+		
+		/* stop */
+		if (strcmp ("Stop", key) == 0)
+		{
+			audacious_drct_stop ();
+			return;
+		}
+		
+		/* prev track */	
+		if (strcmp ("Previous", key) == 0)
+		{
+			audacious_drct_playlist_prev ();
+			return;
+		}
+		
+		/* next track */
+		if (strcmp ("Next", key) == 0)
+		{
+			audacious_drct_playlist_next ();
+			return;
+		}
+	}
+}
+
+void gnome_remote_uninit ()
+{
+	GError *error = NULL;
+	if (media_player_keys_proxy == NULL) return;
+
+	dbus_g_proxy_disconnect_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
+			G_CALLBACK (on_media_player_key_pressed), NULL);
+
+	dbus_g_proxy_call (media_player_keys_proxy,
+				"ReleaseMediaPlayerKeys", &error,
+				G_TYPE_STRING, "Audacious",
+				G_TYPE_INVALID, G_TYPE_INVALID);
+	if (error != NULL) {
+		g_warning ("Could not release media player keys: %s", error->message);
+		g_error_free (error);
+	}
+	g_object_unref(media_player_keys_proxy);
+	media_player_keys_proxy = NULL;
+}
+
+void gnome_remote_init ()
+{
+	DBusGConnection *bus;
+	GError *error = NULL;
+	dbus_g_thread_init();
+
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	if ((bus == NULL) || error) {
+		g_warning ("Error connecting to DBus: %s", error->message);
+	} else {
+		media_player_keys_proxy = dbus_g_proxy_new_for_name (bus,
+			"org.gnome.SettingsDaemon", 
+			"/org/gnome/SettingsDaemon",
+			"org.gnome.SettingsDaemon");
+		if (media_player_keys_proxy == NULL) return;
+
+		dbus_g_proxy_call (media_player_keys_proxy,
+				"GrabMediaPlayerKeys", &error,
+				G_TYPE_STRING, "Audacious",
+				G_TYPE_UINT, 0,
+				G_TYPE_INVALID,
+				G_TYPE_INVALID);
+		if (error != NULL) {
+			g_warning ("Could not release media player keys: %s", error->message);
+			g_error_free (error);
+		}
+
+		dbus_g_object_register_marshaller (hotkey_marshal_VOID__STRING_STRING,
+				G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+
+		dbus_g_proxy_add_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
+				G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+
+		dbus_g_proxy_connect_signal (media_player_keys_proxy, "MediaPlayerKeyPressed",
+				G_CALLBACK (on_media_player_key_pressed), NULL, NULL);
+	}
+}
+
+static void about (void)
+{
+	static GtkWidget *dialog;
+
+	dialog = audacious_info_dialog (_("About Gnome Shortcut Plugin"),
+				_("Gnome Shortcut Plugin\n"
+				"Let's you control the player with Gnome's shortcuts.\n\n"
+				"Copyright (C) 2007 Sascha Hlusiak <contact@saschahlusiak.de>\n\n"
+                         	),
+                         	_("OK"), TRUE, NULL, NULL);
+
+	gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
+			   GTK_SIGNAL_FUNC(gtk_widget_destroyed), &dialog);						
+}
+
+static void init (void)
+{
+	gnome_remote_init();
+	loaded = TRUE;
+}
+
+static void cleanup (void)
+{
+	if (!loaded) return;
+	gnome_remote_uninit();
+	loaded = FALSE;
+}