# HG changeset patch # User Ralf Ertzinger # Date 1190131391 -7200 # Node ID 38375d565192e7244b03033499b69f49fdf7efa6 # Parent 50d151b259bb640cd8443510d5b4f995e8d87e2d# Parent 63feceeb37999bb1bb6461f613bca606cc6210ed branch merge diff -r 50d151b259bb -r 38375d565192 configure.ac --- 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" diff -r 50d151b259bb -r 38375d565192 src/alsa/alsa.h --- 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; diff -r 50d151b259bb -r 38375d565192 src/alsa/audio.c --- 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"); diff -r 50d151b259bb -r 38375d565192 src/alsa/configure.c --- 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"))); diff -r 50d151b259bb -r 38375d565192 src/alsa/init.c --- 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); diff -r 50d151b259bb -r 38375d565192 src/arts/arts.c --- 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 }; diff -r 50d151b259bb -r 38375d565192 src/gnomeshortcuts/Makefile --- /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 diff -r 50d151b259bb -r 38375d565192 src/gnomeshortcuts/gnomeshortcuts.c --- /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 + * 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 + +#include +#include +#include +#include + +#include +#include + +#include +#include + + +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 (¤t_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 \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; +}