diff options
author | Alessio Treglia <alessio@debian.org> | 2012-09-06 17:32:55 +0200 |
---|---|---|
committer | Alessio Treglia <alessio@debian.org> | 2012-09-06 17:32:55 +0200 |
commit | 3c46cd7449c32f71b7b3246b4f32aace3d9e3f84 (patch) | |
tree | 0b1f4f501c9251ffbc622508c726e0ae58370fd0 /src | |
parent | 5927940f774494d20baf7fc501326c2b084e3846 (diff) |
Imported Upstream version 3.3.1
Diffstat (limited to 'src')
169 files changed, 3184 insertions, 8316 deletions
diff --git a/src/Makefile b/src/Makefile index 7021aad..3b0ed74 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,10 +2,6 @@ SUBDIRS = libaudcore libaudgui libaudtag audacious include ../extra.mk -ifeq ($(USE_EGGSM),yes) -SUBDIRS := libeggsmclient ${SUBDIRS} -endif - ifeq ($(USE_DBUS),yes) SUBDIRS := libaudclient audtool ${SUBDIRS} endif diff --git a/src/audacious/Makefile b/src/audacious/Makefile index 22dad64..f6c60ac 100644 --- a/src/audacious/Makefile +++ b/src/audacious/Makefile @@ -5,7 +5,6 @@ SRCS = adder.c \ art.c \ chardet.c \ config.c \ - credits.c \ drct.c \ effect.c \ equalizer.c \ @@ -22,13 +21,13 @@ SRCS = adder.c \ playlist-new.c \ playlist-utils.c \ pluginenum.c \ + plugin-preferences.c \ plugin-registry.c \ plugin-init.c \ plugin-view.c \ probe.c \ probe-buffer.c \ signals.c \ - smclient.c \ ui_plugin_menu.c \ ui_preferences.c \ util.c \ @@ -54,7 +53,6 @@ INCLUDES = api.h \ debug.h \ drct.h \ drct-api.h \ - gtk-compat.h \ i18n.h \ misc.h \ misc-api.h \ @@ -68,11 +66,10 @@ INCLUDES = api.h \ DATA = images/about-logo.png \ images/album.png \ - images/audacious_eq.xpm \ - images/audacious_player.xpm \ - images/audacious_playlist.xpm \ + images/audacious.png \ images/audio.png \ images/connectivity.png \ + images/info.png \ images/menu_playlist.png \ images/menu_plugin.png \ images/menu_queue_toggle.png \ @@ -81,12 +78,6 @@ DATA = images/about-logo.png \ CLEAN = build_stamp.c dbus-client-bindings.h dbus-server-bindings.h -ifeq ($(USE_EGGSM),yes) -EXT_DEPS += ../libeggsmclient/libeggsmclient.a -EGGSM_LIBS = ../libeggsmclient/libeggsmclient.a ${SM_LIBS} ${ICE_LIBS} -EGGSM_CFLAGS = -I../libeggsmclient ${SM_CFLAGS} ${ICE_CFLAGS} -endif - include ../../buildsys.mk ifeq ($(USE_DBUS),yes) @@ -99,15 +90,13 @@ pre-depend: ${DBUS_BINDINGS} CPPFLAGS := -I.. -I../.. \ ${CPPFLAGS} \ ${GLIB_CFLAGS} \ - ${GMODULE_LIBS} \ + ${GMODULE_CFLAGS} \ ${GTHREAD_CFLAGS} \ ${GTK_CFLAGS} \ ${AUDACIOUS_DEFINES} \ ${DBUS_CFLAGS} \ ${REGEX_CFLAGS} \ - ${PTHREAD_CFLAGS} \ -D_AUDACIOUS_CORE \ - ${EGGSM_CFLAGS} \ ${LIBGUESS_CFLAGS} # Essential for efficient FFTs. --jlindgren @@ -118,14 +107,12 @@ LIBS := -L../libaudcore -laudcore \ -L../libaudtag -laudtag \ ${LIBS} -lm \ ${LIBINTL} \ - ${EGGSM_LIBS} \ ${GLIB_LIBS} \ ${GMODULE_LIBS} \ ${GTHREAD_LIBS} \ ${GTK_LIBS} \ ${DBUS_LIBS} \ ${REGEX_LIBS} \ - ${PTHREAD_LIBS} \ ${LIBGUESS_LIBS} DBUS_BINDINGS_SOURCES = objects.xml \ diff --git a/src/audacious/adder.c b/src/audacious/adder.c index 4f24429..22fba2d 100644 --- a/src/audacious/adder.c +++ b/src/audacious/adder.c @@ -2,21 +2,19 @@ * adder.c * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <dirent.h> @@ -78,27 +76,19 @@ static bool_t status_cb (void * unused) gtk_window_set_resizable ((GtkWindow *) status_window, FALSE); gtk_container_set_border_width ((GtkContainer *) status_window, 6); - GtkWidget * vbox = gtk_vbox_new (FALSE, 6); + GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_add ((GtkContainer *) status_window, vbox); status_path_label = gtk_label_new (NULL); -#if GTK_CHECK_VERSION (3, 0, 0) gtk_label_set_width_chars ((GtkLabel *) status_path_label, 40); gtk_label_set_max_width_chars ((GtkLabel *) status_path_label, 40); -#else - gtk_widget_set_size_request (status_path_label, 320, -1); -#endif gtk_label_set_ellipsize ((GtkLabel *) status_path_label, PANGO_ELLIPSIZE_MIDDLE); gtk_box_pack_start ((GtkBox *) vbox, status_path_label, FALSE, FALSE, 0); status_count_label = gtk_label_new (NULL); -#if GTK_CHECK_VERSION (3, 0, 0) gtk_label_set_width_chars ((GtkLabel *) status_count_label, 40); gtk_label_set_max_width_chars ((GtkLabel *) status_count_label, 40); -#else - gtk_widget_set_size_request (status_count_label, 320, -1); -#endif gtk_box_pack_start ((GtkBox *) vbox, status_count_label, FALSE, FALSE, 0); gtk_widget_show_all (status_window); @@ -418,10 +408,12 @@ static bool_t add_finish (void * unused) if (result->play && playlist_entry_count (playlist) > count) { - playlist_set_playing (playlist); - if (! get_bool (NULL, "shuffle")) + if (get_bool (NULL, "shuffle")) + playlist_next_song (playlist, FALSE); + else playlist_set_position (playlist, result->at); + playlist_set_playing (playlist); playback_play (0, FALSE); } diff --git a/src/audacious/api-alias-begin.h b/src/audacious/api-alias-begin.h index cc7c723..3a947fa 100644 --- a/src/audacious/api-alias-begin.h +++ b/src/audacious/api-alias-begin.h @@ -2,21 +2,19 @@ * api-alias-begin.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || defined AUD_API_ALIAS diff --git a/src/audacious/api-alias-end.h b/src/audacious/api-alias-end.h index e7930bc..ac0a2bd 100644 --- a/src/audacious/api-alias-end.h +++ b/src/audacious/api-alias-end.h @@ -2,21 +2,19 @@ * api-alias-end.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || ! defined AUD_API_ALIAS diff --git a/src/audacious/api-declare-begin.h b/src/audacious/api-declare-begin.h index cadc79f..d6c3d34 100644 --- a/src/audacious/api-declare-begin.h +++ b/src/audacious/api-declare-begin.h @@ -2,21 +2,19 @@ * api-declare-begin.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || defined AUD_API_DECLARE_H diff --git a/src/audacious/api-declare-end.h b/src/audacious/api-declare-end.h index df68a68..8ac6135 100644 --- a/src/audacious/api-declare-end.h +++ b/src/audacious/api-declare-end.h @@ -1,21 +1,20 @@ -/* api-declare-end.h +/* + * api-declare-end.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || ! defined AUD_API_DECLARE_H diff --git a/src/audacious/api-define-begin.h b/src/audacious/api-define-begin.h index f193d24..9904761 100644 --- a/src/audacious/api-define-begin.h +++ b/src/audacious/api-define-begin.h @@ -2,21 +2,19 @@ * api-define-begin.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || defined AUD_API_DEFINE_H diff --git a/src/audacious/api-define-end.h b/src/audacious/api-define-end.h index e2801b4..25d874f 100644 --- a/src/audacious/api-define-end.h +++ b/src/audacious/api-define-end.h @@ -2,21 +2,19 @@ * api-define-end.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || ! defined AUD_API_DEFINE_H diff --git a/src/audacious/api-local-begin.h b/src/audacious/api-local-begin.h index 9f11713..88b780d 100644 --- a/src/audacious/api-local-begin.h +++ b/src/audacious/api-local-begin.h @@ -2,21 +2,19 @@ * api-local-begin.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || defined AUD_API_LOCAL_H diff --git a/src/audacious/api-local-end.h b/src/audacious/api-local-end.h index a22d2c6..1aff447 100644 --- a/src/audacious/api-local-end.h +++ b/src/audacious/api-local-end.h @@ -2,21 +2,19 @@ * api-local-end.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #if ! defined AUD_API_NAME || ! defined AUD_API_SYMBOL || ! defined AUD_API_LOCAL_H diff --git a/src/audacious/api.h b/src/audacious/api.h index bfbb940..523c2b9 100644 --- a/src/audacious/api.h +++ b/src/audacious/api.h @@ -2,21 +2,19 @@ * api.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_API_H diff --git a/src/audacious/art.c b/src/audacious/art.c index 3f430f3..36b6a25 100644 --- a/src/audacious/art.c +++ b/src/audacious/art.c @@ -2,21 +2,19 @@ * art.c * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <errno.h> diff --git a/src/audacious/chardet.c b/src/audacious/chardet.c index bdbe026..56a39a8 100644 --- a/src/audacious/chardet.c +++ b/src/audacious/chardet.c @@ -1,20 +1,20 @@ -/* Audacious - * Copyright (C) 2005-2007 Audacious development team. +/* + * chardet.c + * Copyright 2006-2010 Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/audacious/config.c b/src/audacious/config.c index c952e05..828121d 100644 --- a/src/audacious/config.c +++ b/src/audacious/config.c @@ -2,21 +2,19 @@ * config.c * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> @@ -70,6 +68,7 @@ static const char * const core_defaults[] = { "output_buffer_size", "500", "replay_gain_album", "FALSE", "replay_gain_preamp", "0", + "soft_clipping", "FALSE", "software_volume_control", "FALSE", "sw_volume_left", "100", "sw_volume_right", "100", diff --git a/src/audacious/credits.c b/src/audacious/credits.c deleted file mode 100644 index 185fe4f..0000000 --- a/src/audacious/credits.c +++ /dev/null @@ -1,370 +0,0 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2009 Audacious Team - * - * Based on BMP: - * Copyright (C) 2003-2004 BMP development team - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team - * - * 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 - * the Free Software Foundation; under version 3 of the License. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. - */ - -#include <stddef.h> - -#include "config.h" -#include "i18n.h" -#include "misc.h" - -static const char * audacious_brief = - "<big><b>Audacious %s</b></big>\n" - "Copyright (C) 2005-2012 Audacious Team"; - -static const char * const credit_text[] = { - N_("Core developers:"), - "Christian Birchinger", - "Michael Färber", - "Matti Hämäläinen", - "John Lindgren", - "Cristi Măgherușan", - "Tomasz Moń", - "William Pitcock", - "Jonathan Schleifer", - "Ben Tucker", - "Tony Vroon", - "Yoshiki Yazawa", - NULL, - - N_("Graphics:"), - "George Averill", - "Stephan Sokolow", - NULL, - - N_("Default skin:"), - "George Averill", - "Michael Färber", - "William Pitcock", - NULL, - - N_("Plugin development:"), - "Kiyoshi Aman", - "Luca Barbato", - "Daniel Barkalow", - "Michael Färber", - "Shay Green", - "Matti Hämäläinen", - "Sascha Hlusiak", - "John Lindgren", - "Michał Lipski", - "Giacomo Lozito", - "Cristi Măgherușan", - "Boris Mikhaylov", - "Tomasz Moń", - "Sebastian Pipping", - "William Pitcock", - "Derek Pomery", - "Jonathan Schleifer", - "Andrew Shadura", - "Tony Vroon", - "Yoshiki Yazawa", - NULL, - - N_("Patch authors:"), - "Chris Arepantis", - "Anatoly Arzhnikov", - "Alexis Ballier", - "Eric Barch", - "Carlo Bramini", - "Massimo Cavalleri", - "Stefano D'Angelo", - "Jean-Louis Dupond", - "Laszlo Dvornik", - "Ralf Ertzinger", - "Mike Frysinger", - "Mark Glines", - "Hans de Goede", - "David Guglielmi", - "Michael Hanselmann", - "Juho Heikkinen", - "Joseph Jezak", - "Henrik Johansson", - "Jussi Judin", - "Teru Kamogashira", - "Chris Kehler", - "Thomas Lange", - "Mark Loeser", - "Alex Maclean", - "Mikael Magnusson", - "Rodrigo Martins de Matos Ventura", - "Mihai Maruseac", - "Diego Pettenò", - "Mike Ryan", - "Michael Schwendt", - "Edward Sheldrake", - "Kirill Shendrikowski", - "Kazuki Shimura", - "Valentine Sinitsyn", - "Will Storey", - "Johan Tavelin", - "Christoph J. Thompson", - "Bret Towe", - "Peter Wagner", - "John Wehle", - "Ben Wolfson", - "Tim Yamin", - "Ivan N. Zlatev", - NULL, - - N_("1.x developers:"), - "George Averill", - "Daniel Barkalow", - "Christian Birchinger", - "Daniel Bradshaw", - "Adam Cecile", - "Michael Färber", - "Matti Hämäläinen", - "Troels Bang Jensen", - "Giacomo Lozito", - "Cristi Măgherușan", - "Tomasz Moń", - "William Pitcock", - "Derek Pomery", - "Mohammed Sameer", - "Jonathan Schleifer", - "Ben Tucker", - "Tony Vroon", - "Yoshiki Yazawa", - "Eugene Zagidullin", - NULL, - - N_("BMP Developers:"), - "Artem Baguinski", - "Edward Brocklesby", - "Chong Kai Xiong", - "Milosz Derezynski", - "David Lau", - "Ole Andre Vadla Ravnaas", - "Michiel Sikkes", - "Andrei Badea", - "Peter Behroozi", - "Bernard Blackham", - "Oliver Blin", - "Tomas Bzatek", - "Liviu Danicel", - "Jon Dowland", - "Artur Frysiak", - "Sebastian Kapfer", - "Lukas Koberstein", - "Dan Korostelev", - "Jolan Luff", - "Michael Marineau", - "Tim-Philipp Muller", - "Julien Portalier", - "Andrew Ruder", - "Olivier Samyn", - "Martijn Vernooij", - NULL, - - NULL -}; - -static const char * const translators_text[] = { - N_("Argentinian Spanish:"), - "Adrián Ramirez Escalante", - NULL, - N_("Belarusian:"), - "Darafei Praliaskouski", - NULL, - N_("Basque:"), - "Iñaki Larrañaga Murgoitio", - NULL, - N_("Brazilian Portuguese:"), - "Fábio Antunes", - "Karen Eliot", - "Rafael Ferreira", - "Philipi Pinto", - NULL, - N_("Breton:"), - "Thierry Vignaud", - NULL, - N_("Bulgarian:"), - "Andrew Ivanov", - NULL, - N_("Catalan:"), - "Ernest Adrogué", - "Jordi Amenós", - "Juanma Hernández", - NULL, - N_("Chinese:"), - "Tse Chih Chiu", - NULL, - N_("Croatian:"), - "Marin Glibic", - NULL, - N_("Czech:"), - "Petr Pisar", - NULL, - N_("Dutch:"), - "Laurens Buhler", - "Bjorn Roesbeke", - "Tony Vroon", - NULL, - N_("Estonian:"), - "Ivar Smolin", - NULL, - N_("Finnish:"), - "Matti Hämäläinen", - "Elias Julkunen", - "Tuomas Lähteenmäki", - "Pauli Virtanen", - NULL, - N_("French:"), - "Alain-Olivier Breysse", - "Adam Cecile", - "Jean-Alexandre Anglès d'Auriac", - "Stany Henry", - "Stanislas Zeller", - NULL, - N_("German:"), - "Matthias Debus", - "Michael Färber", - "Michael Hanselmann", - "Thomas Lange", - "Carl Trope", - NULL, - N_("Georgian:"), - "George Machitidze", - NULL, - N_("Greek:"), - "Kouzinopoulos Haris", - "Stavros Giannouris", - "Stathis Kamperis", - NULL, - N_("Hindi:"), - "Dhananjaya Sharma", - NULL, - N_("Hungarian:"), - "Laszlo Dvornik", - "Peter Polonkai", - NULL, - N_("Italian:"), - "Alessio D'Ascanio", - "Jacopo Lorenzetti", - "Diego Pettenò", - NULL, - N_("Japanese:"), - "Dai", - "Shuuji Takahashi", - NULL, - N_("Korean:"), - "DongCheon Park", - NULL, - N_("Latvian:"), - "Einars Sprugis", - NULL, - N_("Lithuanian:"), - "Paul Daukas", - "Rimas Kudelis", - "Algimantas Margevičius", - NULL, - N_("Macedonian:"), - "Arangel Angov", - NULL, - N_("Mexican Spanish:"), - "Jorge A. García Sosa", - NULL, - N_("Polish:"), - "Artur Czechowski", - "Michał Kiedrowicz", - "Wojciech Myrda", - "Piotr Sokół", - "Szymon Weihs", - NULL, - N_("Portuguese:"), - "Sérgio Marques", - "Luís Picciochi Oliveira", - NULL, - N_("Romanian:"), - "Daniel Patriche", - "Cristi Măgherușan", - NULL, - N_("Russian:"), - "Sergey V. Mironov", - "Alexandr Orlov", - NULL, - N_("Serbian (Latin):"), - "Strahinja Kustudić", - NULL, - N_("Serbian (Cyrillic):"), - "Мирослав Николић", - "Strahinja Kustudić", - NULL, - N_("Simplified Chinese:"), - "Yang Zhang", - NULL, - N_("Slovak:"), - "Andrej Herceg", - "Tomáš Vadina", - NULL, - N_("Spanish:"), - "Jordi Amenós", - "Jorge Andrés", - "Cosme Domínguez Díaz", - "Adrián Ramirez Escalante", - "Jeki Sinneo Leinos", - "Francisco Javier F. Serrador", - "Gustavo D. Vranjes", - NULL, - N_("Swedish:"), - "Martin Persenius", - NULL, - N_("Traditional Chinese:"), - "Cheng-Wei Chien", - "Sylecn Song", - "Ruei-Yuan Lu", - "Yang Zhang", - NULL, - N_("Turkish:"), - "Murat Şenel", - "Eren Turkay", - NULL, - N_("Ukrainian:"), - "Yuri Chornoivan", - "Kostyantyn Fedenko", - "Rax Garfield", - "Mykola Lynnyk", - NULL, - N_("Vietnamese:"), - "Lê Trường An", - NULL, - N_("Welsh:"), - "Edward Brocklesby", - "William Pitcock", - NULL, - - NULL -}; - -void get_audacious_credits (const char * * brief, const char * const * * - credits, const char * const * * translators) -{ - if (brief != NULL) - *brief = audacious_brief; - if (credits != NULL) - *credits = credit_text; - if (translators != NULL) - *translators = translators_text; -} diff --git a/src/audacious/dbus-service.h b/src/audacious/dbus-service.h index 4d17333..8d773fa 100644 --- a/src/audacious/dbus-service.h +++ b/src/audacious/dbus-service.h @@ -1,21 +1,21 @@ /* - * Audacious: A cross-platform multimedia player - * Copyright (c) 2007 Ben Tucker + * dbus-service.h + * Copyright 2007-2011 Ben Tucker, Yoshiki Yazawa, Matti Hämäläinen, + * John Lindgren, and 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_DBUS_SERVICE_H @@ -216,7 +216,7 @@ bool_t audacious_rc_playqueue_clear(RemoteObject *obj, GError **error); bool_t audacious_rc_playqueue_is_queued(RemoteObject *obj, int pos, bool_t *is_queued, GError **error); bool_t audacious_rc_playlist_ins_url_string(RemoteObject *obj, char *url, int pos, GError **error); bool_t audacious_rc_playlist_enqueue_to_temp(RemoteObject *obj, char *url, GError **error); -bool_t audacious_rc_playlist_add(RemoteObject *obj, gpointer list, GError **error); +bool_t audacious_rc_playlist_add(RemoteObject *obj, void * list, GError **error); /* new on nov 7 */ bool_t audacious_rc_get_eq(RemoteObject *obj, double *preamp, GArray **bands, GError **error); diff --git a/src/audacious/dbus.c b/src/audacious/dbus.c index 5b13c99..a42e1d9 100644 --- a/src/audacious/dbus.c +++ b/src/audacious/dbus.c @@ -1,22 +1,22 @@ /* - * Audacious: A cross-platform multimedia player - * Copyright (c) 2007 Ben Tucker - * Copyright 2009-2011 Audacious development team + * dbus.c + * Copyright 2007-2011 Ben Tucker, Yoshiki Yazawa, William Pitcock, + * Matti Hämäläinen, Andrew Shadoura, John Lindgren, and + * Tomasz Moń * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include "config.h" @@ -56,7 +56,7 @@ G_DEFINE_TYPE (MprisTrackList, mpris_tracklist, G_TYPE_OBJECT) #define DBUS_TYPE_G_STRING_VALUE_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) -static void mpris_playlist_update_hook(gpointer unused, MprisTrackList *obj); +static void mpris_playlist_update_hook(void * unused, MprisTrackList *obj); void audacious_rc_class_init(RemoteObjectClass * klass) { @@ -250,7 +250,7 @@ static void tuple_insert_to_hash(GHashTable * md, const Tuple * tuple, tuple_insert_to_hash_full(md, tuple, key, key); } -static void remove_metadata_value(gpointer value) +static void remove_metadata_value(void * value) { g_value_unset((GValue *) value); g_free((GValue *) value); @@ -259,7 +259,7 @@ static void remove_metadata_value(gpointer value) static GHashTable *make_mpris_metadata(const char * filename, const Tuple * tuple) { GHashTable *md = NULL; - gpointer value; + void * value; md = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, remove_metadata_value); @@ -492,7 +492,7 @@ bool_t mpris_emit_tracklist_change(MprisTrackList * obj, int playlist) return TRUE; } -static void mpris_playlist_update_hook(gpointer unused, MprisTrackList * obj) +static void mpris_playlist_update_hook(void * unused, MprisTrackList * obj) { int playlist = playlist_get_active(); @@ -709,6 +709,9 @@ bool_t audacious_rc_song_title (RemoteObject * obj, unsigned int pos, char * * title, GError * * error) { char * title2 = playlist_entry_get_title (playlist_get_active (), pos, FALSE); + if (! title2) + return FALSE; + * title = strdup (title2); str_unref (title2); return TRUE; @@ -718,6 +721,9 @@ bool_t audacious_rc_song_filename (RemoteObject * obj, unsigned int pos, char * * filename, GError * * error) { char * filename2 = playlist_entry_get_filename (playlist_get_active (), pos); + if (! filename2) + return FALSE; + * filename = strdup (filename2); str_unref (filename2); return TRUE; diff --git a/src/audacious/dbus.h b/src/audacious/dbus.h index 7a2bebf..3a3300d 100644 --- a/src/audacious/dbus.h +++ b/src/audacious/dbus.h @@ -1,21 +1,20 @@ /* - * Audacious: A cross-platform multimedia player - * Copyright (c) 2007 Ben Tucker + * dbus.h + * Copyright 2007 Ben Tucker * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_DBUS_H diff --git a/src/audacious/debug.h b/src/audacious/debug.h index bdadf59..b10fd6c 100644 --- a/src/audacious/debug.h +++ b/src/audacious/debug.h @@ -2,21 +2,19 @@ * debug.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_DEBUG_H diff --git a/src/audacious/drct-api.h b/src/audacious/drct-api.h index fc4c803..6df00f4 100644 --- a/src/audacious/drct-api.h +++ b/src/audacious/drct-api.h @@ -2,21 +2,19 @@ * drct-api.h * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /* Do not include this file directly; use drct.h instead. */ @@ -33,6 +31,7 @@ AUD_VFUNC0 (drct_quit) * and must be freed with str_unref(). */ AUD_VFUNC0 (drct_play) +AUD_VFUNC1 (drct_play_playlist, int, playlist) AUD_VFUNC0 (drct_pause) AUD_VFUNC0 (drct_stop) AUD_FUNC0 (bool_t, drct_get_playing) diff --git a/src/audacious/drct.c b/src/audacious/drct.c index 6ec0dcf..a241357 100644 --- a/src/audacious/drct.c +++ b/src/audacious/drct.c @@ -2,21 +2,19 @@ * drct.c * Copyright 2009-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> @@ -41,16 +39,27 @@ void drct_quit (void) void drct_play (void) { + int playlist = playlist_get_playing (); + if (playlist < 0) + playlist = playlist_get_active (); + + drct_play_playlist (playlist); +} + +void drct_play_playlist (int playlist) +{ + playlist_set_playing (playlist); + if (playback_get_playing ()) { if (playback_get_paused ()) playback_pause (); - else - playback_seek (0); } else { - playlist_set_playing (playlist_get_active ()); + if (playlist_get_position (playlist) < 0) + playlist_next_song (playlist, TRUE); + playback_play (0, FALSE); } } @@ -179,19 +188,31 @@ void drct_set_volume_balance (int balance) void drct_pl_next (void) { bool_t play = playback_get_playing (); - if (playlist_get_playing () < 0) - playlist_set_playing (playlist_get_active ()); - if (playlist_next_song (playlist_get_playing (), get_bool (NULL, "repeat")) && play) + + int playlist = playlist_get_playing (); + if (playlist < 0) + playlist = playlist_get_active (); + + if (playlist_next_song (playlist, get_bool (NULL, "repeat")) && play) + { + playlist_set_playing (playlist); playback_play (0, FALSE); + } } void drct_pl_prev (void) { bool_t play = playback_get_playing (); - if (playlist_get_playing () < 0) - playlist_set_playing (playlist_get_active ()); - if (playlist_prev_song (playlist_get_playing ()) && play) + + int playlist = playlist_get_playing (); + if (playlist < 0) + playlist = playlist_get_active (); + + if (playlist_prev_song (playlist) && play) + { + playlist_set_playing (playlist); playback_play (0, FALSE); + } } static void add_list (Index * filenames, int at, bool_t to_temp, bool_t play) diff --git a/src/audacious/drct.h b/src/audacious/drct.h index b909c21..836a9bc 100644 --- a/src/audacious/drct.h +++ b/src/audacious/drct.h @@ -2,21 +2,19 @@ * drct.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_DRCT_H diff --git a/src/audacious/effect.c b/src/audacious/effect.c index d83c29e..89fa898 100644 --- a/src/audacious/effect.c +++ b/src/audacious/effect.c @@ -2,21 +2,19 @@ * effect.c * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> @@ -24,6 +22,7 @@ #include "debug.h" #include "effect.h" +#include "misc.h" #include "playback.h" #include "plugin.h" #include "plugins.h" @@ -92,6 +91,8 @@ static void effect_process_cb (RunningEffect * effect, EffectProcessState * { if (effect->remove_flag) { + /* call finish twice to completely drain buffers */ + effect->header->finish (state->data, state->samples); effect->header->finish (state->data, state->samples); running_effects = g_list_remove (running_effects, effect); @@ -116,7 +117,10 @@ void effect_flush (void) pthread_mutex_lock (& mutex); for (GList * node = running_effects; node != NULL; node = node->next) - ((RunningEffect *) node->data)->header->flush (); + { + if (PLUGIN_HAS_FUNC (((RunningEffect *) node->data)->header, flush)) + ((RunningEffect *) node->data)->header->flush (); + } pthread_mutex_unlock (& mutex); } @@ -131,32 +135,18 @@ void effect_finish (float * * data, int * samples) pthread_mutex_unlock (& mutex); } -int effect_decoder_to_output_time (int time) -{ - pthread_mutex_lock (& mutex); - - for (GList * node = running_effects; node != NULL; node = node->next) - { - if (PLUGIN_HAS_FUNC (((RunningEffect *) node->data)->header, decoder_to_output_time)) - time = ((RunningEffect *) node->data)->header->decoder_to_output_time (time); - } - - pthread_mutex_unlock (& mutex); - return time; -} - -int effect_output_to_decoder_time (int time) +int effect_adjust_delay (int delay) { pthread_mutex_lock (& mutex); for (GList * node = g_list_last (running_effects); node != NULL; node = node->prev) { - if (PLUGIN_HAS_FUNC (((RunningEffect *) node->data)->header, output_to_decoder_time)) - time = ((RunningEffect *) node->data)->header->output_to_decoder_time (time); + if (PLUGIN_HAS_FUNC (((RunningEffect *) node->data)->header, adjust_delay)) + delay = ((RunningEffect *) node->data)->header->adjust_delay (delay); } pthread_mutex_unlock (& mutex); - return time; + return delay; } static int effect_find_cb (RunningEffect * effect, PluginHandle * plugin) @@ -236,10 +226,7 @@ static void effect_enable (PluginHandle * plugin, EffectPlugin * ep, bool_t else { AUDDBG ("Reset to add/remove %s.\n", plugin_get_name (plugin)); - int time = playback_get_time (); - bool_t paused = playback_get_paused (); - playback_stop (); - playback_play (time, paused); + output_reset (OUTPUT_RESET_EFFECTS_ONLY); } } diff --git a/src/audacious/effect.h b/src/audacious/effect.h index c5e6b18..c663eb7 100644 --- a/src/audacious/effect.h +++ b/src/audacious/effect.h @@ -2,24 +2,21 @@ * effect.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ - #ifndef AUDACIOUS_EFFECT_H #define AUDACIOUS_EFFECT_H @@ -31,8 +28,7 @@ void effect_start (int * channels, int * rate); void effect_process (float * * data, int * samples); void effect_flush (void); void effect_finish (float * * data, int * samples); -int effect_decoder_to_output_time (int time); -int effect_output_to_decoder_time (int time); +int effect_adjust_delay (int delay); bool_t effect_plugin_start (PluginHandle * plugin); void effect_plugin_stop (PluginHandle * plugin); diff --git a/src/audacious/equalizer.c b/src/audacious/equalizer.c index 36d5ce6..ef67b89 100644 --- a/src/audacious/equalizer.c +++ b/src/audacious/equalizer.c @@ -1,14 +1,26 @@ /* - * Equalizer filter, implementation of a 10 band time domain graphic equalizer - * using IIR filters. The IIR filters are implemented using a Direct Form II - * approach, modified (b1 == 0 always) to save computation. + * equalizer.c + * Copyright 2001 Anders Johansson + * Copyright 2010-2011 John Lindgren * - * This software has been released under the terms of the GNU General Public - * license. See http://www.gnu.org/copyleft/gpl.html for details. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Copyright 2001 Anders Johansson <ajh@atri.curtin.edu.au> + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Adapted for Audacious by John Lindgren, 2010-2011 + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +/* + * Anders Johansson prefers float *ptr; formatting. Please keep it that way. + * - tallica */ #include <glib.h> @@ -47,7 +59,7 @@ static float gv[MAX_CHANNELS][EQ_BANDS]; /* Gain factor for each channel and ban static int K; /* Number of used eq bands */ /* 2nd order band-pass filter design */ -static void bp2 (float * a, float * b, float fc, float q) +static void bp2 (float *a, float *b, float fc, float q) { float th = 2 * M_PI * fc; float C = (1 - tanf (th * q / 2)) / (1 + tanf (th * q / 2)); @@ -83,7 +95,7 @@ void eq_set_format (int new_channels, int new_rate) pthread_mutex_unlock (& mutex); } -static void eq_set_bands_real (double preamp, double * values) +static void eq_set_bands_real (double preamp, double *values) { float adj[EQ_BANDS]; for (int i = 0; i < EQ_BANDS; i ++) @@ -94,7 +106,7 @@ static void eq_set_bands_real (double preamp, double * values) gv[c][i] = pow (10, adj[i] / 20) - 1; } -void eq_filter (float * data, int samples) +void eq_filter (float *data, int samples) { int channel; @@ -108,19 +120,19 @@ void eq_filter (float * data, int samples) for (channel = 0; channel < channels; channel ++) { - float * g = gv[channel]; /* Gain factor */ - float * end = data + samples; - float * f; + float *g = gv[channel]; /* Gain factor */ + float *end = data + samples; + float *f; for (f = data + channel; f < end; f += channels) { int k; /* Frequency band index */ - float yt = * f; /* Current input sample */ + float yt = *f; /* Current input sample */ for (k = 0; k < K; k ++) { /* Pointer to circular buffer wq */ - float * wq = wqv[channel][k]; + float *wq = wqv[channel][k]; /* Calculate output from AR part of current filter */ float w = yt * b[k][0] + wq[0] * a[k][0] + wq[1] * a[k][1]; @@ -133,14 +145,14 @@ void eq_filter (float * data, int samples) } /* Calculate output */ - * f = yt; + *f = yt; } } pthread_mutex_unlock (& mutex); } -static void eq_update (void * data, void * user) +static void eq_update (void *data, void *user) { pthread_mutex_lock (& mutex); @@ -168,18 +180,18 @@ void eq_cleanup (void) hook_dissociate ("set equalizer_bands", eq_update); } -void eq_set_bands (const double * values) +void eq_set_bands (const double *values) { - char * string = double_array_to_string (values, EQ_BANDS); + char *string = double_array_to_string (values, EQ_BANDS); g_return_if_fail (string); set_string (NULL, "equalizer_bands", string); g_free (string); } -void eq_get_bands (double * values) +void eq_get_bands (double *values) { memset (values, 0, sizeof (double) * EQ_BANDS); - char * string = get_string (NULL, "equalizer_bands"); + char *string = get_string (NULL, "equalizer_bands"); string_to_double_array (string, values, EQ_BANDS); g_free (string); } diff --git a/src/audacious/equalizer.h b/src/audacious/equalizer.h index d5ab4f9..3acb472 100644 --- a/src/audacious/equalizer.h +++ b/src/audacious/equalizer.h @@ -2,21 +2,19 @@ * equalizer.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_EQUALIZER_H diff --git a/src/audacious/equalizer_preset.c b/src/audacious/equalizer_preset.c index 6d7560c..1ed07dd 100644 --- a/src/audacious/equalizer_preset.c +++ b/src/audacious/equalizer_preset.c @@ -1,20 +1,20 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2011 Audacious team +/* + * equalizer_preset.c + * Copyright 2003-2011 Eugene Zagidullin, William Pitcock, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/audacious/fft.c b/src/audacious/fft.c index abe323f..1531eaf 100644 --- a/src/audacious/fft.c +++ b/src/audacious/fft.c @@ -2,21 +2,19 @@ * fft.c * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <complex.h> diff --git a/src/audacious/fft.h b/src/audacious/fft.h index ccd283a..bb8cba3 100644 --- a/src/audacious/fft.h +++ b/src/audacious/fft.h @@ -2,21 +2,19 @@ * fft.h * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_FFT_H diff --git a/src/audacious/general.c b/src/audacious/general.c index f18b5a9..e0b9ea2 100644 --- a/src/audacious/general.c +++ b/src/audacious/general.c @@ -2,21 +2,19 @@ * general.c * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <gtk/gtk.h> @@ -143,8 +141,6 @@ void general_plugin_stop (PluginHandle * plugin) if (running) general_unload (plugin); - if (gp->settings != NULL) - plugin_preferences_cleanup (gp->settings); if (gp->cleanup != NULL) gp->cleanup (); } diff --git a/src/audacious/general.h b/src/audacious/general.h index a02ff48..c9a7c9e 100644 --- a/src/audacious/general.h +++ b/src/audacious/general.h @@ -2,21 +2,19 @@ * general.h * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_GENERAL_H diff --git a/src/audacious/gtk-compat.h b/src/audacious/gtk-compat.h deleted file mode 100644 index ef07829..0000000 --- a/src/audacious/gtk-compat.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Compatibility macros to make supporting multiple GTK versions easier. - * Public domain. */ - -#ifndef AUD_GTK_COMPAT_H -#define AUD_GTK_COMPAT_H - -#include <string.h> - -#if defined GDK_KEY_Tab && ! defined GDK_Tab -#include <gdk/gdkkeysyms-compat.h> -#endif - -#if ! GTK_CHECK_VERSION (2, 14, 0) -#define gtk_adjustment_get_page_size(a) ((a)->page_size) -#define gtk_adjustment_get_upper(a) ((a)->upper) -#define gtk_dialog_get_action_area(d) ((d)->action_area) -#define gtk_dialog_get_content_area(d) ((d)->vbox) -#define gtk_selection_data_get_data(s) ((s)->data) -#define gtk_selection_data_get_length(s) ((s)->length) -#define gtk_widget_get_window(w) ((w)->window) -#endif - -#if ! GTK_CHECK_VERSION (2, 18, 0) - -static inline void gtk_widget_set_can_default (GtkWidget * w, gboolean b) -{ - if (b) - GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); - else - GTK_WIDGET_UNSET_FLAGS (w, GTK_CAN_DEFAULT); -} - -static inline void gtk_widget_set_can_focus (GtkWidget * w, gboolean b) -{ - if (b) - GTK_WIDGET_SET_FLAGS (w, GTK_CAN_FOCUS); - else - GTK_WIDGET_UNSET_FLAGS (w, GTK_CAN_FOCUS); -} - -#define gtk_widget_get_allocation(w, a) memcpy ((a), & (w)->allocation, sizeof (GtkAllocation)) -#define gtk_widget_get_sensitive GTK_WIDGET_SENSITIVE -#define gtk_widget_get_visible GTK_WIDGET_VISIBLE -#define gtk_widget_is_toplevel GTK_WIDGET_TOPLEVEL -#endif - -#if ! GTK_CHECK_VERSION (2, 20, 0) -#define gtk_widget_is_drawable GTK_WIDGET_DRAWABLE -#endif - -#if ! GTK_CHECK_VERSION (3, 0, 0) - -static inline void gdk_window_get_geometry_compat (GdkWindow * win, int * x, - int * y, int * w, int * h) -{ - gdk_window_get_geometry (win, x, y, w, h, NULL); -} - -#define GtkComboBoxText GtkComboBox -#define gdk_window_get_geometry gdk_window_get_geometry_compat -#define gtk_combo_box_text_new gtk_combo_box_new_text -#define gtk_combo_box_text_new_with_entry gtk_combo_box_entry_new_text -#define gtk_combo_box_text_append_text gtk_combo_box_append_text -#endif - -#if GTK_CHECK_VERSION (3, 0, 0) -#define gtk_range_set_update_policy(...) -#endif - -#endif /* AUD_GTK_COMPAT_H */ diff --git a/src/audacious/history.c b/src/audacious/history.c index 9cc9253..b09903f 100644 --- a/src/audacious/history.c +++ b/src/audacious/history.c @@ -2,21 +2,19 @@ * history.c * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/audacious/i18n.h b/src/audacious/i18n.h index 4bdb988..5b5205c 100644 --- a/src/audacious/i18n.h +++ b/src/audacious/i18n.h @@ -1,20 +1,20 @@ -/* Audacious - * Copyright (c) 2006-2007 William Pitcock +/* + * i18n.h + * Copyright 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_I18N_H diff --git a/src/audacious/images/album.png b/src/audacious/images/album.png Binary files differindex decbcdb..a47bc7d 100644 --- a/src/audacious/images/album.png +++ b/src/audacious/images/album.png diff --git a/src/audacious/images/audacious.png b/src/audacious/images/audacious.png Binary files differnew file mode 100644 index 0000000..5de1b7f --- /dev/null +++ b/src/audacious/images/audacious.png diff --git a/src/audacious/images/audacious_eq.xpm b/src/audacious/images/audacious_eq.xpm deleted file mode 100644 index 7c28e99..0000000 --- a/src/audacious/images/audacious_eq.xpm +++ /dev/null @@ -1,93 +0,0 @@ -/* XPM */ -static char *audacious_eq_icon[] = { -/* columns rows colors chars-per-pixel */ -"48 48 39 1", -" c #e36d45", -". c #e3734d", -"X c #e47650", -"o c #e57a54", -"O c #e57d59", -"+ c #e6805d", -"@ c #e68462", -"# c #e78867", -"$ c #e88665", -"% c #e88866", -"& c #e88b6b", -"* c #e98f70", -"= c #e99274", -"- c #ea9678", -"; c #ea997c", -": c #eb9d82", -"> c #eca086", -", c #eda48b", -"< c #eda88f", -"1 c #eeab93", -"2 c #efae98", -"3 c #efb09a", -"4 c #f0b29c", -"5 c #f0b5a0", -"6 c #f2bba7", -"7 c #f2bca9", -"8 c #f3c5b4", -"9 c #f4c7b8", -"0 c #f4cabb", -"q c #f5cec0", -"w c #f6d6cb", -"e c #f7d8ce", -"r c #f7dad0", -"t c #f8dcd3", -"y c #f8e0d7", -"u c #f9e3db", -"i c #fae6e0", -"p c #fae8e2", -"a c white", -/* pixels */ -"<2211111<<<<,,:,,:::::::::::-=---=====&=&&&=&&&&", -"255544422211111<<<<<<::::::::::----======&&&&&##", -"25554442222111<<,<,,:<:::::::------===&=*&&&%%$&", -"1544442222111<<<<<<:<:<:::::-:----=====&*&&&&%$%", -"2554442221111<<<:<:<::<::::::----=====&=&&%&$%%#", -"154442222111<<,<,,<:<::::-:-----====&&=&&&&&%$@$", -"14422222111<<<,,,:<<:::::::-:----====&&&&&&%%$@%", -"1442222211<<<<,,:<:::::::--:=--===&==&&&&&%%$@@%", -"1442221211<<<,,,,<,:::::-:----=-====&&&&&$$$$@@@", -"124222111<<<,,,,::::::;::-:---===*=&=&&&&&%@@@@#", -"1422211111<<<,,,,:::::;;-:----===&=&&&&&$$$#@@@@", -"12222111<taaaaa4,:::::::---=======&=&&&&%$$@@@+@", -"<222111<<taaaaa4::::::-----=-====&&&&&&&$$#@+@+@", -"<2211111<taaaaa4,::::--::---==**=&&&&&$%$#@@@++@", -"<21211<<<taaaaa3:::::::----====*=&&&&%%%$@@+@+O@", -"<21211<<<taaaaa3::::-:---=====**&&&&&%%$@@@@+++@", -"<111<<<<<taaaaa3::::;;----*-*=&&&&&&#%$$@@@+++O+", -"<111<<<,,raaaaa3:::;;;---*-*==*&&&&&%%$@@@@+++++", -",1111<<,,raaaaa2::;;-----111111&&&&%%$#@@@+++OO+", -"<11<<<<,<raaaaa2;;;;;---:aaaaap&&&%%$$@@@+++OOO+", -",8ppppi8>raaaaa3:;;;--*-;aaaaap&&%&$$$@@++@OOOOO", -",qaaaaa0,raaaaa1;;;----=-aaaaap&&%#$@@@+@+O+OOO+", -",qaaaaa0,raaaaa2;;;---==;aaaaap&&%%$#@@@OO+OOooO", -",qaaaaa0>eaaaaa1;;---===-aaaaap&%%$$@++@++OOOOo+", -",0aaaaa0,eaaaaa1;;----==-aaaaap#&$$#@@+++OOOOooO", -",0aaaaa0>raaaaa1-;--====-aaaaap#:ttttt7++OOooooO", -",qaaaaa0:taaaaa1--;==***-aaaaap$,aaaaaq+OOOooooO", -":0aaaaa9:eaaaaa1-wuuuuu&-aaaaap$,aaaaaq+OOOooo.O", -",0aaaaa0:eaaaaa1-paaaaa==aaaaap$,aaaaaqOOOooo.oO", -":0aaaaa9:eaaaaa1=paaaaa&=aaaaap@,aaaaaqOOOoooo.O", -":qaaaaa9:waaaaa1-paaaaa=-aaaaap@>aaaaaqOoOoooXXO", -":0aaaaa9:waaaaa1=paaaaa&*aaaaap@,aaaaa0O;77777*o", -">0aaaaa9:eaaaaa1=paaaaa&=aaaaap@>aaaaaqO4aaaaa3o", -":0aaaaa8;eaaaaa,-paaaaa&=aaaaai@>aaaaaqo4aaaaa3o", -":0aaaaa8;eaaaaa,=paaaaa&=aaaaap+>aaaaa0O5aaaaa3o", -":9aaaaa9;eaaaaa<*paaaaa&&aaaaai@>aaaaaqo4aaaaa3o", -":0aaaaa8;eaaaaa,&paaaaa&=aaaaap+>aaaaa0o4aaaaa2o", -":9aaaaa8-eaaaaa,=paaaaa%&aaaaau+:aaaaa0o4aaaaa2X", -":9aaaaa8;waaaaa,=paaaaa%=aaaaai+>aaaaa0o4aaaaa2X", -":9aaaaa8-eaaaaa,&paaaaa#&aaaaai+:aaaaa0o4aaaaa3X", -";8aaaaa8-waaaaa,*paaaaa#*aaaaapO:aaaaa0o3aaaaa2X", -";8aaaaa8-waaaaa,*paaaaa#&aaaaaiO:aaaaa0X3aaaaa2.", -";9aaaaa8-waaaaa>&paaaaa@&aaaaaiO:aaaaa0X3aaaaa1o", -";9aaaaa8=eaaaaa,&paaaaa@&aaaaauO:aaaaa0.3aaaaa1.", -";8aaaaa8*waaaaa:&paaaaa@&aaaaauO:aaaaa0.2aaaaa1.", -";8aaaaa8=waaaaa>&paaaaa@&aaaaaiO;aaaaa0.3aaaaa2.", -";;;;;=====***&*&#&###@@+++OOOOOooXoX..... . .", -"---=--====*****&&&&#####@@@@++++OOOOOooooXXX...o" -}; diff --git a/src/audacious/images/audacious_player.xpm b/src/audacious/images/audacious_player.xpm deleted file mode 100644 index f850210..0000000 --- a/src/audacious/images/audacious_player.xpm +++ /dev/null @@ -1,165 +0,0 @@ -/* XPM */ -static char * audacious_player_xpm[] = { -"48 48 114 2", -" c None", -". c #000000", -"+ c #202020", -"@ c #5E5E5E", -"# c #909090", -"$ c #B1B1B1", -"% c #CACACA", -"& c #D5D5D5", -"* c #B0B0B0", -"= c #8E8E8E", -"- c #5A5A5A", -"; c #1D1D1D", -"> c #030303", -", c #4D4D4D", -"' c #A8A8A8", -") c #D9D9D9", -"! c #D8D8D8", -"~ c #A4A4A4", -"{ c #484848", -"] c #020202", -"^ c #3C3C3C", -"/ c #B8B8B8", -"( c #B5B5B5", -"_ c #393939", -": c #090909", -"< c #858585", -"[ c #828282", -"} c #070707", -"| c #141414", -"1 c #AEAEAE", -"2 c #ADADAD", -"3 c #121212", -"4 c #B9B9B9", -"5 c #ABABAB", -"6 c #AAAAAA", -"7 c #080808", -"8 c #D0D0D0", -"9 c #BCBCBC", -"0 c #CBCBCB", -"a c #818181", -"b c #3A3A3A", -"c c #8C8C8C", -"d c #535353", -"e c #414141", -"f c #2D2D2D", -"g c #010101", -"h c #161616", -"i c #4E4E4E", -"j c #9E9E9E", -"k c #373737", -"l c #B6B6B6", -"m c #313131", -"n c #B4B4B4", -"o c #9A9A9A", -"p c #0C0C0C", -"q c #474747", -"r c #A6A6A6", -"s c #939393", -"t c #282828", -"u c #A5A5A5", -"v c #1F1F1F", -"w c #D6D6D6", -"x c #0E0E0E", -"y c #2B2B2B", -"z c #1B1B1B", -"A c #A9A9A9", -"B c #1C1C1C", -"C c #5B5B5B", -"D c #464646", -"E c #777777", -"F c #595959", -"G c #8D8D8D", -"H c #CFCFCF", -"I c #929292", -"J c #6D6D6D", -"K c #111111", -"L c #494949", -"M c #5D5D5D", -"N c #353535", -"O c #242424", -"P c #757575", -"Q c #C9C9C9", -"R c #D4D4D4", -"S c #404040", -"T c #D3D3D3", -"U c #ACACAC", -"V c #B2B2B2", -"W c #CCCCCC", -"X c #646464", -"Y c #737373", -"Z c #A3A3A3", -"` c #131313", -" . c #8B8B8B", -".. c #7B7B7B", -"+. c #212121", -"@. c #505050", -"#. c #1E1E1E", -"$. c #050505", -"%. c #5C5C5C", -"&. c #969696", -"*. c #191919", -"=. c #101010", -"-. c #BDBDBD", -";. c #B7B7B7", -">. c #878787", -",. c #898989", -"'. c #343434", -"). c #1A1A1A", -"!. c #BBBBBB", -"~. c #3B3B3B", -"{. c #C2C2C2", -"]. c #838383", -"^. c #808080", -"/. c #AFAFAF", -" . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . + @ # $ % & & % * = - ; . . . . . . . . . . ", -" . . . . . . . . > , ' ) ) ) ) ) ) ) ) ) ) ) ! ~ { ] . . . . . . . . ", -" . . . . . . . . ^ / ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ( _ . . . . . . . . ", -" . . . . . . . : < ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) [ } . . . . . . . ", -" . . . . . . . | 1 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) 2 | . . . . . . . ", -" . . . . . . 3 4 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) / 3 . . . . . . ", -" . . . . . . : 5 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) 6 7 . . . . . . ", -" . . . . . . . [ ) ) ) ) ) ) ) ) ) ) ) ) 8 9 9 0 ) ) ) ) ) ) ) ) ) ) ) ) a . . . . . . . ", -" . . . . . . b ) ) ) ) ) ) ) ) ! c d e f g . . . h i j ) ) ) ) ) ) ) ) ) ) k . . . . . . ", -" . . . . . ] l ) ) ) ) ) ) ) ! d . . . . . . . . . . . m n ) ) ) ) ) ) ) ) ( ] . . . . . ", -" . . . . . . { ) ) ) ) ) ) ) ) o . . . . . . . . . . . . . p 2 ) ) ) ) ) ) ) ) q . . . . . . ", -" . . . . . . r ) ) ) ) ) ) ) ) s . . . . . . . . . . . . . . t ! ) ) ) ) ) ) ) u . . . . . . ", -" . . . . . v ! ) ) ) ) ) ) ) ) w d x ; y y y z . . . . . . . . A ) ) ) ) ) ) ) ! B . . . . . ", -". . . . . . C ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) D . . . . . . . E ) ) ) ) ) ) ) ) F . . . . . . ", -". . . . . . G ) ) ) ) ) ) ) ) ) ) ) ) ) ) H I J K . . . . . . . L ) ) ) ) ) ) ) ) c . . . . . . ", -". . . . . . $ ) ) ) ) ) ) ) ) ) ) ) 6 M N : . . . . . . . . . . O ) ) ) ) ) ) ) ) * . . . . . . ", -". . . . . . 0 ) ) ) ) ) ) ) ) ) ! P > . . . . . . . . . . . . . : ) ) ) ) ) ) ) ) Q . . . . . . ", -". . . . . . R ) ) ) ) ) ) ) ) ) - . . . . . . . . . . . . . . . : ) ) ) ) ) ) ) ) R . . . . . . ", -". . . . . . R ) ) ) ) ) ) ) ) < . . . . . . . . . . . . . . . . S ) ) ) ) ) ) ) ) R . . . . . . ", -". . . . . . 0 ) ) ) ) ) ) ) T p . . . . . . D 2 U m . . . . . . F ) ) ) ) ) ) ) ) Q . . . . . . ", -". . . . . . V ) ) ) ) ) ) ) W . . . . . . . G ) ) X . . . . . . Y ) ) ) ) ) ) ) ) * . . . . . . ", -". . . . . . # ) ) ) ) ) ) ) W . . . . . . . k 5 Z ` . . . . . . .) ) ) ) ) ) ) ) G . . . . . . ", -". . . . . . M ) ) ) ) ) ) ) w x . . . . . . . . . . . . . . . . ..) ) ) ) ) ) ) ) C . . . . . . ", -" . . . . . +.) ) ) ) ) ) ) ) @.. . . . . . . . . . . . . . . . q ) ) ) ) ) ) ) ) #.. . . . . ", -" . . . . . . A ) ) ) ) ) ) ) V $.. . . . . . . . . . . . . . . %.) ) ) ) ) ) ) ' . . . . . . ", -" . . . . . . , ) ) ) ) ) ) ) ) &.p . . . . . . > *.K . . . . =.-.) ) ) ) ) ) ) , . . . . . . ", -" . . . . . > ;.) ) ) ) ) ) ) ) -.^ ] . . m >.% ) w ,.'.).{ !.) ) ) ) ) ) ) l > . . . . . ", -" . . . . . . ~.) ) ) ) ) ) ) ) ) ) {. .~ ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) _ . . . . . . ", -" . . . . . . . ].) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) a . . . . . . . ", -" . . . . . . : 6 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) 6 7 . . . . . . ", -" . . . . . . 3 / ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) / 3 . . . . . . ", -" . . . . . . . | 1 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) U 3 . . . . . . . ", -" . . . . . . . } [ ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ^.} . . . . . . . ", -" . . . . . . . . b ;.) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) n k . . . . . . . . ", -" . . . . . . . . > , ' ) ) ) ) ) ) ) ) ) ) ) ! ~ { ] . . . . . . . . ", -" . . . . . . . . . . v C = /.Q R R Q 1 c F B . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . . . . . . . ", -" . . . . . . . . . . "}; diff --git a/src/audacious/images/audacious_playlist.xpm b/src/audacious/images/audacious_playlist.xpm deleted file mode 100644 index d6f7046..0000000 --- a/src/audacious/images/audacious_playlist.xpm +++ /dev/null @@ -1,97 +0,0 @@ -/* XPM */ -static char *audacious_playlist_icon[] = { -/* columns rows colors chars-per-pixel */ -"48 48 43 1", -" c #e36e45", -". c #e3734c", -"X c #e47650", -"o c #e57a54", -"O c #e57d59", -"+ c #e6815d", -"@ c #e68462", -"# c #e78867", -"$ c #e88665", -"% c #e88866", -"& c #e88b6b", -"* c #e98f70", -"= c #e99273", -"- c #ea9679", -"; c #eb997c", -": c #eb9d82", -"> c #eca086", -", c #eda48b", -"< c #eda88f", -"1 c #eeaa93", -"2 c #efae98", -"3 c #efb09a", -"4 c #f0b29c", -"5 c #f0b5a1", -"6 c #f0b8a5", -"7 c #f1bcaa", -"8 c #f2c0ae", -"9 c #f3c3b3", -"0 c #f4c7b8", -"q c #f4cabb", -"w c #f5cec1", -"e c #f5d1c4", -"r c #f6d5c9", -"t c #f7d8cd", -"y c #f8ddd4", -"u c #f8e0d7", -"i c #f9e3db", -"p c #fae6e0", -"a c #fae8e2", -"s c #fcf0eb", -"d c #fcf4f1", -"f c #fdf9f7", -"g c white", -/* pixels */ -"<22111111<<<<,,,::,:::::;;;;;;----====*=&=&&&&#&", -"2555444423111<<<<<<,,>>>:>:;;;;;---====**&&&&&#&", -"25444424312111<<<,,,,>,>>:::;;;----===&==&&&%%%#", -"1554442222111<<<,,,,,>:::::;;;----=====&&&&&%%%#", -"25544422211111<<,,,,::>::;;;;;---=====**&&&%%%$#", -"19aat22uaaaapppppppppppipppiiipiiiiiu4*&4iuuue$$", -"19ggi22sggggggggggggggggggggggggggggg7*&7ggggp%$", -"10ggi24dggggggggggggggggggggggggggggg7*&7ggggp@#", -"17trq21errreeeeeewwwwwwwqwqqq0qq00000,&&,99993@$", -"1333221111<<<,,,,,>::::;;;;-;--===***&&%##$#$@@@", -"1432211111<<<,,,>>>>:::;;;;---===***&&&&####$@@@", -"<9aar11upaappppppipipiiiiiiiu5===***&&&%2uyyyw+@", -"<0ggu11dggggggggggggggggggggg9=&=&&*&&%%7ggggp@@", -"10ggu11dggggggggggggggggggggg9===&&&&&%%7ggggp+@", -"<39961<6766666665554544442222:&=**&&&#%%=,,>>;O@", -"<11111<<<<<,,>::::::;;----=====&*&&&&%%$@@@@++++", -"<1111<<1<,,>,>::::;;;-;----=*=&&&&&%%%$$@@@+++O@", -"<0ggy<<sgggggggggggggggggggggggggggs%%$$6ggggpO+", -"<9ggy<<sgggggggggggggggggggggggggggs%%$@6ggggpO+", -",9ggy<<sgggggggggggggggggggggggggggs%%$@6ggggiO+", -",2774<,,,,>:>:::;;;----====&&&&&&%%%$$$+@+++OOO+", -",111<<,,>>>>::::;;;---=-===&=&&&%#%%$@@+++++OOO+", -",<<<,,,6665555545444422112111111<#$$@@@@&:>;;-OO", -",9ggy,,fggggggggggggggggggggggggd$$$@@+@6ggggpoO", -",9ggy,:fggggggggggggggggggggggggf$$@@@++6ggggpoO", -",7ggy,,fggggggggggggggggggggggggd$$@@+@+5ggggioO", -"><<,,,:,>::::;;;---=====&&&&&%%%$$@@+@++OOOooooO", -":<,,>,>::::;;;;----====&&=&&&%%%$@@@@OOOOOOooo.O", -":1664,:65535444442121211<11<1<,,,,>>,&+O&:;;;-oO", -",7ggy><gggggggggggggggggggggggggggggg6OO5ggggp.O", -":6ggu:,gggggggggggggggggggggggggggggg3OO5ggggi.o", -":5ppe:,ippiiiiiiiiiuiiuiuuuuuuyyyyuyy1Oo<yyyy0Xo", -">,,:::::::;;----====&&&&&%%%$$@@++++OOOOoooXXX.o", -":,,::::::;;;;--=-==***&%&&&%%$@@@+++OOOooooo.X.o", -":1ww9:<qqqqqq000000000099,%%@@@@+++OOoOo-76662.o", -":6ggy:1gggggggggggggggggg7$$@@@+++OOOOoo4ggggi.o", -":6ggy:2gggggggggggggggggg6%@@@++++OOOOoo4ggggi.X", -":2ppw:1iiiiiiiiuuiuiuuuiu2@@@@+++OOOoooo,yyyy0.o", -";::::;;;;--======&=&&&%%%$$@+@+++OOOoooo.X.... X", -";,::;;;;----=====&&&&%#$$$@@@+++OOOoOoo.o... ..X", -";1wq7;1qqq0q0000900999999979979777777;oo-66661 o", -";5ggy;5gggggggggggggggggggggggggggggg3..3ggggi .", -";5ggy;6gggggggggggggggggggggggggggggg2o.3ggggi X", -"-1wq7;<q0q000000099999979779777777777-X.=66561 .", -";;;:=;-====**=&&&&#%#$@@@@+++OOOOoooo..o.... .", -";;;;;;=-====*&&&&&#%$$@@++++OOOOooooo..... .", -";;;-;-====***&*&&###$@@@++O+OOOooo.o.... .. .", -"----=-======&=&&&#&##$$$@@@@+++OOOOOOoooo.o....o" -}; diff --git a/src/audacious/images/audio.png b/src/audacious/images/audio.png Binary files differindex 4cbf294..a41d51a 100644 --- a/src/audacious/images/audio.png +++ b/src/audacious/images/audio.png diff --git a/src/audacious/images/connectivity.png b/src/audacious/images/connectivity.png Binary files differindex d6be3b8..2d80e79 100644 --- a/src/audacious/images/connectivity.png +++ b/src/audacious/images/connectivity.png diff --git a/src/audacious/images/info.png b/src/audacious/images/info.png Binary files differnew file mode 100644 index 0000000..91e2c17 --- /dev/null +++ b/src/audacious/images/info.png diff --git a/src/audacious/images/menu_playlist.png b/src/audacious/images/menu_playlist.png Binary files differindex a96f899..2bd5af9 100644 --- a/src/audacious/images/menu_playlist.png +++ b/src/audacious/images/menu_playlist.png diff --git a/src/audacious/images/menu_plugin.png b/src/audacious/images/menu_plugin.png Binary files differindex 507ff2a..d90ab66 100644 --- a/src/audacious/images/menu_plugin.png +++ b/src/audacious/images/menu_plugin.png diff --git a/src/audacious/images/menu_queue_toggle.png b/src/audacious/images/menu_queue_toggle.png Binary files differindex d2cfa4e..6cf6443 100644 --- a/src/audacious/images/menu_queue_toggle.png +++ b/src/audacious/images/menu_queue_toggle.png diff --git a/src/audacious/images/playlist.png b/src/audacious/images/playlist.png Binary files differindex 787a1e0..2574ef0 100644 --- a/src/audacious/images/playlist.png +++ b/src/audacious/images/playlist.png diff --git a/src/audacious/images/plugins.png b/src/audacious/images/plugins.png Binary files differindex 47d3e42..da9f9e1 100644 --- a/src/audacious/images/plugins.png +++ b/src/audacious/images/plugins.png diff --git a/src/audacious/interface.c b/src/audacious/interface.c index 58427ef..eabcb76 100644 --- a/src/audacious/interface.c +++ b/src/audacious/interface.c @@ -1,23 +1,20 @@ /* - * Audacious2 - * Copyright (c) 2008 William Pitcock <nenolod@dereferenced.org> - * Copyright (c) 2008-2009 Tomasz Moń <desowin@gmail.com> - * Copyright (c) 2010-2011 John Lindgren <john.lindgren@tds.net> + * interface.c + * Copyright 2010-2011 John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <gtk/gtk.h> @@ -164,6 +161,7 @@ void interface_add_plugin_widget (PluginHandle * plugin, GtkWidget * widget) GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title ((GtkWindow *) window, plugin_get_name (plugin)); gtk_window_set_default_size ((GtkWindow *) window, 300, 200); + gtk_window_set_has_resize_grip ((GtkWindow *) window, FALSE); gtk_container_add ((GtkContainer *) window, widget); g_signal_connect (window, "delete-event", (GCallback) delete_cb, plugin); gtk_widget_show_all (window); diff --git a/src/audacious/interface.h b/src/audacious/interface.h index 20e413a..8bc5727 100644 --- a/src/audacious/interface.h +++ b/src/audacious/interface.h @@ -1,23 +1,20 @@ /* - * Audacious2 - * Copyright (c) 2008 William Pitcock <nenolod@dereferenced.org> - * Copyright (c) 2008-2009 Tomasz Moń <desowin@gmail.com> - * Copyright (c) 2011 John Lindgren <john.lindgren@tds.net> + * interface.h + * Copyright 2010-2011 John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef __AUDACIOUS2_INTERFACE_H__ diff --git a/src/audacious/main.c b/src/audacious/main.c index 47883fc..ceb42a4 100644 --- a/src/audacious/main.c +++ b/src/audacious/main.c @@ -1,26 +1,20 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2011 Audacious development team. +/* + * main.c + * Copyright 2007-2011 William Pitcock and John Lindgren * - * Based on BMP: - * Copyright (C) 2003-2004 BMP development team. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * 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 - * the Free Software Foundation; under version 3 of the License. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <errno.h> @@ -43,11 +37,6 @@ #include "dbus.h" #endif -#ifdef USE_EGGSM -#include "eggdesktopfile.h" -#include "eggsmclient.h" -#endif - #include "debug.h" #include "drct.h" #include "equalizer.h" @@ -268,9 +257,6 @@ static void parse_options (int * argc, char *** argv) context = g_option_context_new(_("- play multimedia files")); g_option_context_add_main_entries(context, cmd_entries, PACKAGE); g_option_context_add_group(context, gtk_get_option_group(FALSE)); -#ifdef USE_EGGSM - g_option_context_add_group(context, egg_sm_client_get_option_group()); -#endif if (!g_option_context_parse(context, argc, argv, &error)) { @@ -412,7 +398,7 @@ static void do_remote (void) static void do_commands (void) { - bool_t resume = get_bool (NULL, "resume_playback_on_startup"); + bool_t resume = TRUE; Index * filenames = convert_filenames (); if (filenames) @@ -453,16 +439,12 @@ static void init_one (void) init_paths (); make_dirs (); + setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, aud_paths[AUD_PATH_LOCALE_DIR]); bind_textdomain_codeset (PACKAGE, "UTF-8"); bindtextdomain (PACKAGE "-plugins", aud_paths[AUD_PATH_LOCALE_DIR]); bind_textdomain_codeset (PACKAGE "-plugins", "UTF-8"); textdomain (PACKAGE); - -#ifdef USE_EGGSM - egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_NORMAL); - egg_set_desktop_file (aud_paths[AUD_PATH_DESKTOP_FILE]); -#endif } static void init_two (int * p_argc, char * * * p_argv) @@ -470,7 +452,6 @@ static void init_two (int * p_argc, char * * * p_argv) if (! headless) { g_thread_init (NULL); - gtk_rc_add_default_file (aud_paths[AUD_PATH_GTKRC_FILE]); gtk_init (p_argc, p_argv); } @@ -485,9 +466,6 @@ static void init_two (int * p_argc, char * * * p_argv) #ifdef HAVE_SIGWAIT signals_init (); #endif -#ifdef USE_EGGSM - smclient_init (); -#endif AUDDBG ("Loading lowlevel plugins.\n"); start_plugins_one (); diff --git a/src/audacious/main.h b/src/audacious/main.h index 3b85f08..81f9a14 100644 --- a/src/audacious/main.h +++ b/src/audacious/main.h @@ -2,21 +2,19 @@ * main.h * Copyright 2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /* Header for all those files that have just one or two public identifiers. */ @@ -56,9 +54,6 @@ void mpris_signals_cleanup (void); /* signals.c */ void signals_init (void); -/* smclient.c */ -void smclient_init (void); - /* ui_albumart.c */ char * get_associated_image_file (const char * filename); diff --git a/src/audacious/misc-api.h b/src/audacious/misc-api.h index bd24303..2346e92 100644 --- a/src/audacious/misc-api.h +++ b/src/audacious/misc-api.h @@ -2,21 +2,19 @@ * misc-api.h * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /* Do not include this file directly; use misc.h instead. */ @@ -59,10 +57,6 @@ AUD_FUNC2 (int, get_int, const char *, section, const char *, name) AUD_VFUNC3 (set_double, const char *, section, const char *, name, double, value) AUD_FUNC2 (double, get_double, const char *, section, const char *, name) -/* credits.c */ -AUD_VFUNC3 (get_audacious_credits, const char * *, brief, - const char * const * *, credits, const char * const * *, translators) - /* equalizer.c */ AUD_VFUNC1 (eq_set_bands, const double *, values) AUD_VFUNC1 (eq_get_bands, double *, values) @@ -97,6 +91,9 @@ AUD_VFUNC1 (interface_uninstall_toolbar, void *, button) /* main.c */ AUD_FUNC1 (const char *, get_path, int, path) +/* output.c */ +AUD_VFUNC1 (output_reset, int, type) + /* probe.c */ AUD_FUNC2 (PluginHandle *, file_find_decoder, const char *, filename, bool_t, fast) @@ -119,7 +116,7 @@ AUD_VFUNC2 (plugin_menu_remove, int, id, MenuFunc, func) /* ui_preferences.c */ AUD_VFUNC4 (create_widgets_with_domain, /* GtkWidget * */ void *, box, - PreferencesWidget *, widgets, int, count, const char *, domain) + const PreferencesWidget *, widgets, int, n_widgets, const char *, domain) AUD_VFUNC0 (show_prefs_window) /* util.c */ diff --git a/src/audacious/misc.h b/src/audacious/misc.h index 090b607..c214eb6 100644 --- a/src/audacious/misc.h +++ b/src/audacious/misc.h @@ -2,21 +2,19 @@ * misc.h * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_MISC_H @@ -38,7 +36,7 @@ enum { AUD_PATH_USER_DIR, AUD_PATH_USER_PLUGIN_DIR, AUD_PATH_PLAYLISTS_DIR, - AUD_PATH_GTKRC_FILE, + AUD_PATH_GTKRC_FILE, /* deprecated */ AUD_PATH_COUNT }; @@ -47,6 +45,8 @@ typedef struct { float preamp, bands[10]; } EqualizerPreset; +enum {OUTPUT_RESET_EFFECTS_ONLY, OUTPUT_RESET_SOFT, OUTPUT_RESET_HARD}; + enum { AUD_MENU_MAIN, AUD_MENU_PLAYLIST, diff --git a/src/audacious/mpris-signals.c b/src/audacious/mpris-signals.c index e7f61fb..7ecf1b8 100644 --- a/src/audacious/mpris-signals.c +++ b/src/audacious/mpris-signals.c @@ -1,26 +1,20 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2011 Audacious development team. +/* + * mpris-signals.c + * Copyright 2011 John Lindgren * - * Based on BMP: - * Copyright (C) 2003-2004 BMP development team. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * 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 - * the Free Software Foundation; under version 3 of the License. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifdef USE_DBUS diff --git a/src/audacious/mpris_player.xml b/src/audacious/mpris_player.xml index 460e5bd..c954f8b 100644 --- a/src/audacious/mpris_player.xml +++ b/src/audacious/mpris_player.xml @@ -1,21 +1,22 @@ <?xml version="1.0" encoding="UTF-8" ?> <!-- - - Audacious: A cross-platform multimedia player - - Copyright (c) 2007 William Pitcock - - Copyright (c) 2007 Ben Tucker - - - - 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 - - the Free Software Foundation; under version 3 of the License. - - - - This program 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 this program. If not, see <http://www.gnu.org/licenses>. + * mpris_player.xml + * Copyright 2007 William Pitcock and Ben Tucker + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. --> <node name="/Player"> diff --git a/src/audacious/mpris_root.xml b/src/audacious/mpris_root.xml index 3b59845..7d84ded 100644 --- a/src/audacious/mpris_root.xml +++ b/src/audacious/mpris_root.xml @@ -1,20 +1,22 @@ <?xml version="1.0" encoding="UTF-8" ?> <!-- - - Audacious: A cross-platform multimedia player - - 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 - - the Free Software Foundation; under version 3 of the License. - - - - This program 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 this program. If not, see <http://www.gnu.org/licenses>. + * mpris_root.xml + * Copyright 2007 William Pitcock + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. --> <node name="/"> diff --git a/src/audacious/mpris_tracklist.xml b/src/audacious/mpris_tracklist.xml index 826fde2..46859a2 100644 --- a/src/audacious/mpris_tracklist.xml +++ b/src/audacious/mpris_tracklist.xml @@ -1,21 +1,22 @@ <?xml version="1.0" encoding="UTF-8" ?> <!-- - - Audacious: A cross-platform multimedia player - - Copyright (c) 2007 William Pitcock - - Copyright (c) 2007 Ben Tucker - - - - 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 - - the Free Software Foundation; under version 3 of the License. - - - - This program 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 this program. If not, see <http://www.gnu.org/licenses>. + * mpris_tracklist.xml + * Copyright 2007 William Pitcock and Ben Tucker + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. --> <node name="/TrackList"> diff --git a/src/audacious/objects.xml b/src/audacious/objects.xml index 1c62c75..4b3317f 100644 --- a/src/audacious/objects.xml +++ b/src/audacious/objects.xml @@ -1,20 +1,22 @@ <?xml version="1.0" encoding="UTF-8" ?> <!-- - - Audacious: A cross-platform multimedia player - - Copyright (c) 2007 Ben Tucker - - - - 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 - - the Free Software Foundation; under version 3 of the License. - - - - This program 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 this program. If not, see <http://www.gnu.org/licenses>. + * objects.xml + * Copyright 2007 Ben Tucker + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. --> <!-- diff --git a/src/audacious/output.c b/src/audacious/output.c index eeee3f5..ae3d874 100644 --- a/src/audacious/output.c +++ b/src/audacious/output.c @@ -1,28 +1,29 @@ /* * output.c - * Copyright 2009-2010 John Lindgren + * Copyright 2009-2012 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ -#include <glib.h> #include <math.h> #include <pthread.h> +#include <stdlib.h> #include <string.h> +#include <unistd.h> + +#include <libaudcore/hook.h> #include "debug.h" #include "effect.h" @@ -30,166 +31,126 @@ #include "misc.h" #include "output.h" #include "playback.h" +#include "plugin.h" #include "plugins.h" #include "vis_runner.h" #define SW_VOLUME_RANGE 40 /* decibels */ -static OutputPlugin * cop = NULL; +static pthread_mutex_t mutex_major = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mutex_minor = PTHREAD_MUTEX_INITIALIZER; + +#define LOCK_MAJOR pthread_mutex_lock (& mutex_major) +#define UNLOCK_MAJOR pthread_mutex_unlock (& mutex_major) +#define LOCK_MINOR pthread_mutex_lock (& mutex_minor) +#define UNLOCK_MINOR pthread_mutex_unlock (& mutex_minor) +#define LOCK_ALL do { LOCK_MAJOR; LOCK_MINOR; } while (0) +#define UNLOCK_ALL do { UNLOCK_MINOR; UNLOCK_MAJOR; } while (0) + +/* State variables. State changes that are allowed between LOCK_MINOR and + * UNLOCK_MINOR (all others must take place between LOCK_ALL and UNLOCK_ALL): + * s_paused -> TRUE or FALSE, s_aborted -> TRUE, s_resetting -> TRUE */ + +static bool_t s_input; /* input plugin connected */ +static bool_t s_output; /* output plugin connected */ +static bool_t s_gain; /* replay gain info set */ +static bool_t s_paused; /* paused */ +static bool_t s_aborted; /* writes aborted */ +static bool_t s_resetting; /* resetting output system */ -void output_get_volume (int * l, int * r) +static OutputPlugin * cop; +static int seek_time; +static int in_format, in_channels, in_rate; +static int out_format, out_channels, out_rate; +static int64_t in_frames, out_frames; +static ReplayGainInfo gain_info; + +static bool_t change_op; +static OutputPlugin * new_op; + +static inline int FR2MS (int64_t f, int r) + { return (f > 0) ? (f * 1000 + r / 2) / r : (f * 1000 - r / 2) / r; } + +static inline int get_format (void) { - if (get_bool (NULL, "software_volume_control")) - { - * l = get_int (NULL, "sw_volume_left"); - * r = get_int (NULL, "sw_volume_right"); - } - else if (cop != NULL && cop->get_volume != NULL) - cop->get_volume (l, r); - else + switch (get_int (NULL, "output_bit_depth")) { - * l = 0; - * r = 0; + case 16: return FMT_S16_NE; + case 24: return FMT_S24_NE; + case 32: return FMT_S32_NE; + default: return FMT_FLOAT; } } -void output_set_volume (int l, int r) +/* assumes LOCK_ALL, s_output */ +static void cleanup_output (void) { - if (get_bool (NULL, "software_volume_control")) + if (! (s_paused || s_aborted) && PLUGIN_HAS_FUNC (cop, drain)) { - set_int (NULL, "sw_volume_left", l); - set_int (NULL, "sw_volume_right", r); + UNLOCK_MINOR; + cop->drain (); + LOCK_MINOR; } - else if (cop != NULL && cop->set_volume != NULL) - cop->set_volume (l, r); -} -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static bool_t locked = FALSE; - -#define LOCK do {pthread_mutex_lock (& mutex); locked = TRUE;} while (0) -#define UNLOCK do {locked = FALSE; pthread_mutex_unlock (& mutex);} while (0) -#define LOCKED g_return_if_fail (locked) -#define LOCKED_RET(a) g_return_val_if_fail (locked, a) -#define LOCK_VIS do {vis_runner_lock (); LOCK;} while (0) -#define UNLOCK_VIS do {UNLOCK; vis_runner_unlock ();} while (0) -#define LOCKED_VIS g_return_if_fail (locked && vis_runner_locked ()) -#define LOCKED_VIS_RET(a) g_return_val_if_fail (locked && vis_runner_locked (), a) - -static bool_t opened = FALSE; -static bool_t leave_open = FALSE; - -static bool_t waiting, aborted, paused; -static int decoder_format, decoder_channels, decoder_rate, effect_channels, - effect_rate, output_format, output_channels, output_rate; -static int64_t frames_written; -static bool_t have_replay_gain; -static ReplayGainInfo replay_gain_info; - -static void reset_time (void) -{ - LOCKED_VIS; - g_return_if_fail (cop->set_written_time != NULL); - vis_runner_time_offset (- cop->written_time ()); - cop->set_written_time (0); -} + s_output = FALSE; -static void drain (void) -{ - LOCKED; - g_return_if_fail (cop->drain != NULL); - cop->drain (); -} + if (PLUGIN_HAS_FUNC (cop, close_audio)) + cop->close_audio (); -static void real_close (void) -{ - LOCKED_VIS; + effect_flush (); vis_runner_start_stop (FALSE, FALSE); - cop->close_audio (); - opened = FALSE; - leave_open = FALSE; } -static bool_t open_audio (int format, int rate, int channels) +/* assumes LOCK_ALL, s_input, s_output */ +static void apply_pause (void) { - LOCKED_VIS_RET (FALSE); - g_return_val_if_fail (! opened, FALSE); - - decoder_format = format; - decoder_channels = channels; - decoder_rate = rate; - effect_channels = channels; - effect_rate = rate; - effect_start (& effect_channels, & effect_rate); - eq_set_format (effect_channels, effect_rate); - - if (leave_open && effect_channels == output_channels && effect_rate == - output_rate) - { - reset_time (); - opened = TRUE; - } - else - { - if (leave_open) - { - drain (); - real_close (); - } + if (PLUGIN_HAS_FUNC (cop, pause)) + cop->pause (s_paused); - int depth = get_int (NULL, "output_bit_depth"); - output_format = (depth == 32) ? FMT_S32_NE : (depth == 24) ? FMT_S24_NE - : (depth == 16) ? FMT_S16_NE : FMT_FLOAT; - output_channels = effect_channels; - output_rate = effect_rate; + vis_runner_start_stop (TRUE, s_paused); +} - if (cop->open_audio (output_format, output_rate, output_channels)) - { - vis_runner_start_stop (TRUE, FALSE); - opened = TRUE; - } - } +/* assumes LOCK_ALL, s_input */ +static void setup_output (void) +{ + int format = get_format (); + int channels = in_channels; + int rate = in_rate; - leave_open = FALSE; - waiting = FALSE; - aborted = FALSE; - paused = FALSE; - frames_written = 0; - have_replay_gain = FALSE; + effect_start (& channels, & rate); + eq_set_format (channels, rate); - return opened; -} + if (s_output && format == out_format && channels == out_channels && rate == + out_rate && ! PLUGIN_HAS_FUNC (cop, force_reopen)) + return; -static bool_t output_open_audio (int format, int rate, int channels) -{ - g_return_val_if_fail (cop != NULL, FALSE); - LOCK_VIS; - bool_t success = open_audio (format, rate, channels); - UNLOCK_VIS; - return success; -} + if (s_output) + cleanup_output (); -static void set_gain (ReplayGainInfo * info) -{ - LOCKED; - g_return_if_fail (opened && ! waiting); + if (! cop || ! PLUGIN_HAS_FUNC (cop, open_audio) || ! cop->open_audio (format, rate, channels)) + return; - AUDDBG ("Replay Gain info:\n"); - AUDDBG (" album gain: %f dB\n", info->album_gain); - AUDDBG (" album peak: %f\n", info->album_peak); - AUDDBG (" track gain: %f dB\n", info->track_gain); - AUDDBG (" track peak: %f\n", info->track_peak); + s_output = TRUE; - have_replay_gain = TRUE; - memcpy (& replay_gain_info, info, sizeof (ReplayGainInfo)); + out_format = format; + out_channels = channels; + out_rate = rate; + out_frames = 0; + + apply_pause (); } -static void output_set_replaygain_info (ReplayGainInfo * info) +/* assumes LOCK_MINOR, s_input, s_output */ +static void flush_output (void) { - g_return_if_fail (cop != NULL); - LOCK; - set_gain (info); - UNLOCK; + if (PLUGIN_HAS_FUNC (cop, flush)) + { + cop->flush (0); + out_frames = 0; + } + + effect_flush (); + vis_runner_flush (); } static void apply_replay_gain (float * data, int samples) @@ -199,24 +160,23 @@ static void apply_replay_gain (float * data, int samples) float factor = powf (10, get_double (NULL, "replay_gain_preamp") / 20); - if (have_replay_gain) + if (s_gain) { + float peak; + if (get_bool (NULL, "replay_gain_album")) { - factor *= powf (10, replay_gain_info.album_gain / 20); - - if (get_bool (NULL, "enable_clipping_prevention") && - replay_gain_info.album_peak * factor > 1) - factor = 1 / replay_gain_info.album_peak; + factor *= powf (10, gain_info.album_gain / 20); + peak = gain_info.album_peak; } else { - factor *= powf (10, replay_gain_info.track_gain / 20); - - if (get_bool (NULL, "enable_clipping_prevention") && - replay_gain_info.track_peak * factor > 1) - factor = 1 / replay_gain_info.track_peak; + factor *= powf (10, gain_info.track_gain / 20); + peak = gain_info.track_peak; } + + if (get_bool (NULL, "enable_clipping_prevention") && peak * factor > 1) + factor = 1 / peak; } else factor *= powf (10, get_double (NULL, "default_gain") / 20); @@ -225,338 +185,391 @@ static void apply_replay_gain (float * data, int samples) audio_amplify (data, 1, samples, & factor); } -static void apply_software_volume (float * data, int channels, int frames) +static void apply_software_volume (float * data, int channels, int samples) { - float left_factor, right_factor; - float factors[channels]; - int channel; - if (! get_bool (NULL, "software_volume_control")) return; int l = get_int (NULL, "sw_volume_left"); int r = get_int (NULL, "sw_volume_right"); + if (l == 100 && r == 100) return; - left_factor = (l == 0) ? 0 : powf (10, (float) SW_VOLUME_RANGE * (l - 100) / 100 / 20); - right_factor = (r == 0) ? 0 : powf (10, (float) SW_VOLUME_RANGE * (r - 100) / 100 / 20); + float lfactor = (l == 0) ? 0 : powf (10, (float) SW_VOLUME_RANGE * (l - 100) / 100 / 20); + float rfactor = (r == 0) ? 0 : powf (10, (float) SW_VOLUME_RANGE * (r - 100) / 100 / 20); + float factors[channels]; if (channels == 2) { - factors[0] = left_factor; - factors[1] = right_factor; + factors[0] = lfactor; + factors[1] = rfactor; } else { - for (channel = 0; channel < channels; channel ++) - factors[channel] = MAX (left_factor, right_factor); + for (int c = 0; c < channels; c ++) + factors[c] = MAX (lfactor, rfactor); } - audio_amplify (data, channels, frames, factors); + audio_amplify (data, channels, samples / channels, factors); } -static void write_processed (void * data, int samples) +/* assumes LOCK_ALL, s_output */ +static void write_output_raw (void * data, int samples) { - LOCKED_VIS; + void * buffer = NULL; - if (! samples) - return; + vis_runner_pass_audio (FR2MS (out_frames, out_rate), data, samples, + out_channels, out_rate); + out_frames += samples / out_channels; - vis_runner_pass_audio (cop->written_time (), data, samples, output_channels, - output_rate); eq_filter (data, samples); - apply_software_volume (data, output_channels, samples / output_channels); + apply_software_volume (data, out_channels, samples); - void * allocated = NULL; + if (get_bool (NULL, "soft_clipping")) + audio_soft_clip (data, samples); - if (output_format != FMT_FLOAT) + if (out_format != FMT_FLOAT) { - void * new = g_malloc (FMT_SIZEOF (output_format) * samples); - audio_to_int (data, new, output_format, samples); - data = new; - g_free (allocated); - allocated = new; + buffer = malloc (FMT_SIZEOF (out_format) * samples); + audio_to_int (data, buffer, out_format, samples); + data = buffer; } - while (! aborted) + while (! (s_aborted || s_resetting)) { - int ready = (cop->buffer_free != NULL) ? cop->buffer_free () / - FMT_SIZEOF (output_format) : output_channels * (output_rate / 50); + bool_t blocking = ! PLUGIN_HAS_FUNC (cop, buffer_free); + int ready; + + if (blocking) + ready = out_channels * (out_rate / 50); + else + ready = cop->buffer_free () / FMT_SIZEOF (out_format); + ready = MIN (ready, samples); - cop->write_audio (data, FMT_SIZEOF (output_format) * ready); - data = (char *) data + FMT_SIZEOF (output_format) * ready; - samples -= ready; - if (! samples) + if (PLUGIN_HAS_FUNC (cop, write_audio)) + { + cop->write_audio (data, FMT_SIZEOF (out_format) * ready); + data = (char *) data + FMT_SIZEOF (out_format) * ready; + samples -= ready; + } + + if (samples == 0) break; - waiting = TRUE; - UNLOCK_VIS; + UNLOCK_MINOR; - if (cop->period_wait != NULL) - cop->period_wait (); - else if (cop->buffer_free != NULL) - g_usleep (20000); + if (! blocking) + { + if (PLUGIN_HAS_FUNC (cop, period_wait)) + cop->period_wait (); + else + usleep (20000); + } - LOCK_VIS; - waiting = FALSE; + LOCK_MINOR; } - g_free (allocated); + free (buffer); } -static void write_audio (void * data, int size) +/* assumes LOCK_ALL, s_input, s_output */ +static void write_output (void * data, int size) { - LOCKED; - g_return_if_fail (opened && ! waiting); - - int samples = size / FMT_SIZEOF (decoder_format); - frames_written += samples / decoder_channels; + void * buffer = NULL; - void * allocated = NULL; + int samples = size / FMT_SIZEOF (in_format); + in_frames += samples / in_channels; - if (decoder_format != FMT_FLOAT) + if (in_format != FMT_FLOAT) { - float * new = g_malloc (sizeof (float) * samples); - audio_from_int (data, decoder_format, new, samples); - data = new; - g_free (allocated); - allocated = new; + buffer = malloc (sizeof (float) * samples); + audio_from_int (data, in_format, buffer, samples); + data = buffer; } - apply_replay_gain (data, samples); float * fdata = data; + apply_replay_gain (fdata, samples); effect_process (& fdata, & samples); - data = fdata; + write_output_raw (fdata, samples); - if (data != allocated) - { - g_free (allocated); - allocated = NULL; - } + free (buffer); +} + +/* assumes LOCK_ALL, s_output */ +static void finish_effects (void) +{ + float * data = NULL; + int samples = 0; - write_processed (data, samples); - g_free (allocated); + effect_finish (& data, & samples); + write_output_raw (data, samples); } -static void output_write_audio (void * data, int size) +bool_t output_open_audio (int format, int rate, int channels) { - g_return_if_fail (cop != NULL); - LOCK_VIS; - write_audio (data, size); - UNLOCK_VIS; + LOCK_ALL; + + s_input = TRUE; + s_gain = s_paused = s_aborted = FALSE; + seek_time = 0; + + in_format = format; + in_channels = channels; + in_rate = rate; + in_frames = 0; + + setup_output (); + + UNLOCK_ALL; + return TRUE; } -static void close_audio (void) +void output_set_replaygain_info (const ReplayGainInfo * info) { - LOCKED; - g_return_if_fail (opened && ! waiting); - opened = FALSE; + LOCK_ALL; - if (! leave_open) + if (s_input) { - effect_flush (); - real_close (); + memcpy (& gain_info, info, sizeof (ReplayGainInfo)); + s_gain = TRUE; + + AUDDBG ("Replay Gain info:\n"); + AUDDBG (" album gain: %f dB\n", info->album_gain); + AUDDBG (" album peak: %f\n", info->album_peak); + AUDDBG (" track gain: %f dB\n", info->track_gain); + AUDDBG (" track peak: %f\n", info->track_peak); } -} -static void output_close_audio (void) -{ - g_return_if_fail (cop != NULL); - LOCK_VIS; - close_audio (); - UNLOCK_VIS; + UNLOCK_ALL; } -static void do_pause (bool_t p) +void output_write_audio (void * data, int size) { - LOCKED_VIS; - g_return_if_fail (opened); - cop->pause (p); - vis_runner_start_stop (TRUE, p); - paused = p; -} + LOCK_ALL; -static void output_pause (bool_t p) -{ - g_return_if_fail (cop != NULL); - LOCK_VIS; - do_pause (p); - UNLOCK_VIS; + if (s_input) + { + while ((! s_output || s_resetting) && ! s_aborted) + { + UNLOCK_ALL; + usleep (20000); + LOCK_ALL; + } + + if (! s_aborted) + write_output (data, size); + } + + UNLOCK_ALL; } -static void flush (int time) +void output_abort_write (void) { - LOCKED_VIS; - g_return_if_fail (opened); - - aborted = FALSE; + LOCK_MINOR; - /* When playback is started from the middle of a song, flush() is called - * before any audio is actually written in order to set the time counter. - * In this case, we do not want to cut off the end of the previous song, so - * we do not actually flush. */ - if (! frames_written) + if (s_input) { - g_return_if_fail (cop->set_written_time != NULL); - vis_runner_time_offset (time - cop->written_time ()); - cop->set_written_time (time); - } - else - { - vis_runner_flush (); - effect_flush (); - cop->flush (effect_decoder_to_output_time (time)); + s_aborted = TRUE; + + if (s_output) + flush_output (); } - frames_written = time * (int64_t) decoder_rate / 1000; + UNLOCK_MINOR; } -static void output_flush (int time) +void output_pause (bool_t pause) { - g_return_if_fail (cop != NULL); - LOCK_VIS; - flush (time); - UNLOCK_VIS; + LOCK_MINOR; + + if (s_input) + { + s_paused = pause; + + if (s_output) + apply_pause (); + } + + UNLOCK_MINOR; } -static int written_time (void) +int output_written_time (void) { - LOCKED_RET (0); - g_return_val_if_fail (opened && ! waiting, 0); - return frames_written * (int64_t) 1000 / decoder_rate; + LOCK_MINOR; + int time = 0; + + if (s_input) + time = seek_time + FR2MS (in_frames, in_rate); + + UNLOCK_MINOR; + return time; } -static int output_written_time (void) +void output_set_time (int time) { - g_return_val_if_fail (cop != NULL, 0); - LOCK; - int time = written_time (); - UNLOCK; - return time; + LOCK_ALL; + + if (s_input) + { + s_aborted = FALSE; + seek_time = time; + in_frames = 0; + } + + UNLOCK_ALL; + + /* See comment in playback_seek(). */ + event_queue ("playback seek", NULL); } -static void write_buffers (void) +bool_t output_is_open (void) { - LOCKED; - float * data = NULL; - int samples = 0; - effect_finish (& data, & samples); - write_processed (data, samples); + LOCK_MINOR; + bool_t is_open = s_input; + UNLOCK_MINOR; + return is_open; } -static void set_leave_open (void) +int output_get_time (void) { - LOCKED; - g_return_if_fail (opened && ! waiting); + LOCK_MINOR; + int time = 0, delay = 0; - if (! paused) + if (s_input) { - write_buffers (); - leave_open = TRUE; + if (s_output && PLUGIN_HAS_FUNC (cop, output_time)) + delay = FR2MS (out_frames, out_rate) - cop->output_time (); + + delay = effect_adjust_delay (delay); + time = FR2MS (in_frames, in_rate); + time = seek_time + MAX (time - delay, 0); } -} -static bool_t output_buffer_playing (void) -{ - g_return_val_if_fail (cop != NULL, FALSE); - LOCK_VIS; - set_leave_open (); - UNLOCK_VIS; - return FALSE; + UNLOCK_MINOR; + return time; } -static void abort_write (void) +int output_get_raw_time (void) { - LOCKED; - g_return_if_fail (opened); - aborted = TRUE; - cop->flush (cop->output_time ()); + LOCK_MINOR; + int time = 0; + + if (s_output && PLUGIN_HAS_FUNC (cop, output_time)) + time = cop->output_time (); + + UNLOCK_MINOR; + return time; } -static void output_abort_write (void) +void output_close_audio (void) { - g_return_if_fail (cop != NULL); - LOCK; - abort_write (); - UNLOCK; + LOCK_ALL; + + if (s_input) + { + s_input = FALSE; + + if (s_output && ! (s_paused || s_aborted || s_resetting)) + finish_effects (); /* first time for end of song */ + } + + UNLOCK_ALL; } -const struct OutputAPI output_api = -{ - .open_audio = output_open_audio, - .set_replaygain_info = output_set_replaygain_info, - .write_audio = output_write_audio, - .close_audio = output_close_audio, - - .pause = output_pause, - .flush = output_flush, - .written_time = output_written_time, - .buffer_playing = output_buffer_playing, - .abort_write = output_abort_write, -}; - -static int output_time (void) +void output_drain (void) { - LOCKED_RET (0); - g_return_val_if_fail (opened || leave_open, 0); - return cop->output_time (); + LOCK_ALL; + + if (! s_input && s_output) + { + finish_effects (); /* second time for end of playlist */ + cleanup_output (); + } + + UNLOCK_ALL; } -int get_output_time (void) +void output_reset (int type) { - g_return_val_if_fail (cop != NULL, 0); - LOCK; + LOCK_MINOR; - int time = 0; - if (opened) + s_resetting = TRUE; + + if (s_output) + flush_output (); + + UNLOCK_MINOR; + LOCK_ALL; + + if (s_output && type != OUTPUT_RESET_EFFECTS_ONLY) + cleanup_output (); + + if (type == OUTPUT_RESET_HARD) { - time = effect_output_to_decoder_time (output_time ()); - time = MAX (0, time); + if (cop && PLUGIN_HAS_FUNC (cop, cleanup)) + cop->cleanup (); + + if (change_op) + cop = new_op; + + if (cop && PLUGIN_HAS_FUNC (cop, init) && ! cop->init ()) + cop = NULL; } - UNLOCK; - return time; + if (s_input) + setup_output (); + + s_resetting = FALSE; + + UNLOCK_ALL; } -int get_raw_output_time (void) +void output_get_volume (int * left, int * right) { - g_return_val_if_fail (cop != NULL, 0); - LOCK; - int time = output_time (); - UNLOCK; - return time; + LOCK_MINOR; + + * left = * right = 0; + + if (get_bool (NULL, "software_volume_control")) + { + * left = get_int (NULL, "sw_volume_left"); + * right = get_int (NULL, "sw_volume_right"); + } + else if (cop && PLUGIN_HAS_FUNC (cop, get_volume)) + cop->get_volume (left, right); + + UNLOCK_MINOR; } -void output_drain (void) +void output_set_volume (int left, int right) { - g_return_if_fail (cop != NULL); - LOCK_VIS; + LOCK_MINOR; - if (leave_open) + if (get_bool (NULL, "software_volume_control")) { - write_buffers (); - drain (); - real_close (); + set_int (NULL, "sw_volume_left", left); + set_int (NULL, "sw_volume_right", right); } + else if (cop && PLUGIN_HAS_FUNC (cop, set_volume)) + cop->set_volume (left, right); - UNLOCK_VIS; + UNLOCK_MINOR; } static bool_t probe_cb (PluginHandle * p, PluginHandle * * pp) { OutputPlugin * op = plugin_get_header (p); - g_return_val_if_fail (op != NULL && op->init != NULL, TRUE); - if (! op->init ()) - return TRUE; + if (! op || (PLUGIN_HAS_FUNC (op, init) && ! op->init ())) + return TRUE; /* keep searching */ - if (op->cleanup != NULL) + if (PLUGIN_HAS_FUNC (op, cleanup)) op->cleanup (); * pp = p; - return FALSE; + return FALSE; /* stop searching */ } PluginHandle * output_plugin_probe (void) @@ -568,32 +581,18 @@ PluginHandle * output_plugin_probe (void) PluginHandle * output_plugin_get_current (void) { - return (cop != NULL) ? plugin_by_header (cop) : NULL; + return cop ? plugin_by_header (cop) : NULL; } bool_t output_plugin_set_current (PluginHandle * plugin) { - if (cop != NULL) - { - if (playback_get_playing ()) - playback_stop (); + change_op = TRUE; + new_op = plugin ? plugin_get_header (plugin) : NULL; + output_reset (OUTPUT_RESET_HARD); - if (cop->cleanup != NULL) - cop->cleanup (); + bool_t success = (cop == new_op); + change_op = FALSE; + new_op = NULL; - cop = NULL; - } - - if (plugin != NULL) - { - OutputPlugin * op = plugin_get_header (plugin); - g_return_val_if_fail (op != NULL && op->init != NULL, FALSE); - - if (! op->init ()) - return FALSE; - - cop = op; - } - - return TRUE; + return success; } diff --git a/src/audacious/output.h b/src/audacious/output.h index c096f8e..8d8ffe1 100644 --- a/src/audacious/output.h +++ b/src/audacious/output.h @@ -1,42 +1,45 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2009 Audacious development team +/* + * output.h + * Copyright 2010-2011 John Lindgren * - * Based on BMP: - * Copyright (C) 2003-2004 BMP development team + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * 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 - * the Free Software Foundation; under version 3 of the License. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_OUTPUT_H #define AUDACIOUS_OUTPUT_H -#include "plugin.h" +#include <libaudcore/core.h> +#include "types.h" -extern const struct OutputAPI output_api; +bool_t output_open_audio (int format, int rate, int channels); +void output_set_replaygain_info (const ReplayGainInfo * info); +void output_write_audio (void * data, int length); +void output_abort_write (void); +void output_pause (bool_t pause); +int output_written_time (void); +void output_set_time (int time); -void output_get_volume(int * l, int * r); -void output_set_volume(int l, int r); - -int get_output_time (void); -int get_raw_output_time (void); +bool_t output_is_open (void); +int output_get_time (void); +int output_get_raw_time (void); +void output_close_audio (void); void output_drain (void); +void output_get_volume (int * left, int * right); +void output_set_volume (int left, int right); + PluginHandle * output_plugin_probe (void); PluginHandle * output_plugin_get_current (void); bool_t output_plugin_set_current (PluginHandle * plugin); diff --git a/src/audacious/playback.c b/src/audacious/playback.c index eb90209..69b76ab 100644 --- a/src/audacious/playback.c +++ b/src/audacious/playback.c @@ -1,22 +1,20 @@ /* * playback.c - * Copyright 2005-2011 Audacious Development Team + * Copyright 2009-2012 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> @@ -33,9 +31,19 @@ #include "output.h" #include "playback.h" #include "playlist.h" +#include "plugin.h" static void playback_start (int playlist, int entry, int seek_time, bool_t pause); +static const struct OutputAPI output_api = { + .open_audio = output_open_audio, + .set_replaygain_info = output_set_replaygain_info, + .write_audio = output_write_audio, + .abort_write = output_abort_write, + .pause = output_pause, + .written_time = output_written_time, + .flush = output_set_time}; + static InputPlayback playback_api; static bool_t playing = FALSE; @@ -167,7 +175,7 @@ int playback_get_time (void) time = current_decoder->get_time (& playback_api); if (time < 0) - time = get_output_time (); + time = output_get_time (); return time - time_offset; } @@ -177,23 +185,12 @@ void playback_play (int seek_time, bool_t pause) g_return_if_fail (! playing); int playlist = playlist_get_playing (); - - if (playlist == -1) - { - playlist = playlist_get_active (); - playlist_set_playing (playlist); - } + if (playlist < 0) + return; int entry = playlist_get_position (playlist); - - if (entry == -1) - { - playlist_next_song (playlist, TRUE); - entry = playlist_get_position (playlist); - - if (entry == -1) - return; - } + if (entry < 0) + return; failed_entries = 0; playback_start (playlist, entry, seek_time, pause); @@ -224,6 +221,7 @@ static void playback_cleanup (void) playing = FALSE; event_queue_cancel ("playback ready", NULL); + event_queue_cancel ("playback seek", NULL); event_queue_cancel ("info change", NULL); event_queue_cancel ("title change", NULL); @@ -331,6 +329,8 @@ static void * playback_thread (void * unused) file, seekable ? time_offset + initial_seek : 0, seekable ? playback_entry_get_end_time () : -1, paused); + output_close_audio (); + if (file) vfs_fclose (file); @@ -388,7 +388,12 @@ void playback_seek (int time) current_decoder->mseek (& playback_api, time_offset + CLAMP (time, 0, current_length)); - hook_call ("playback seek", NULL); + /* If the plugin is using our output system, don't call "playback seek" + * immediately but wait for output_set_time() to be called. This ensures + * that a "playback seek" handler can call playback_get_time() and get the + * new time. */ + if (! output_is_open ()) + hook_call ("playback seek", NULL); } static void set_data (InputPlayback * p, void * data) @@ -502,10 +507,6 @@ void playback_get_volume (int * l, int * r) void playback_set_volume (int l, int r) { - int h_vol[2] = {l, r}; - - hook_call ("volume set", h_vol); - if (playing && playback_get_ready () && current_decoder && current_decoder->set_volume && current_decoder->set_volume (l, r)) return; diff --git a/src/audacious/playback.h b/src/audacious/playback.h index 109f9c9..faf045d 100644 --- a/src/audacious/playback.h +++ b/src/audacious/playback.h @@ -1,23 +1,20 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2011 Audacious development team +/* + * playback.h + * Copyright 2006-2011 William Pitcock and John Lindgren * - * Based on BMP: - * Copyright (C) 2003-2004 BMP development team + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * 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 - * the Free Software Foundation; under version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * This program 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_PLAYBACK_H diff --git a/src/audacious/playlist-api.h b/src/audacious/playlist-api.h index c3777b3..112b594 100644 --- a/src/audacious/playlist-api.h +++ b/src/audacious/playlist-api.h @@ -1,22 +1,20 @@ /* * playlist-api.h - * Copyright 2010-2011 John Lindgren + * Copyright 2010-2012 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /* Do not include this file directly; use playlist.h instead. */ @@ -42,9 +40,8 @@ AUD_VFUNC3 (playlist_reorder, int, from, int, to, int, count) /* Closes a playlist. CAUTION: The playlist is not saved, and no confirmation * is presented to the user. If <playlist> is the only playlist, a new playlist * is added. If <playlist> is the active playlist, another playlist is marked - * active. If <playlist> is the one from which the last song played was taken, - * playback is stopped. In this case, calls to playlist_get_playing() will - * return -1, and the behavior of drct_play() is unspecified. */ + * active. If <playlist> is the currently playing playlist, playback is + * stopped. In this case, calls to playlist_get_playing() will return -1. */ AUD_VFUNC1 (playlist_delete, int, playlist) /* Returns a unique non-negative integer which can be used to identify a given @@ -70,22 +67,20 @@ AUD_VFUNC2 (playlist_set_title, int, playlist, const char *, title) /* Returns the title associated with a playlist. */ AUD_FUNC1 (char *, playlist_get_title, int, playlist) -/* Marks a playlist as active. This is the playlist which the user will see and - * on which most DRCT functions will take effect. */ +/* Sets the active playlist. This is the playlist that user interfaces will + * show to the user. */ AUD_VFUNC1 (playlist_set_active, int, playlist) -/* Returns the number of the playlist marked active. */ +/* Returns the number of the active playlist. */ AUD_FUNC0 (int, playlist_get_active) -/* Sets the playlist in which playback will begin when drct_play() is called. - * This does not mark the playlist as active. If a song is already playing, it - * will be stopped. If <playlist> is negative, calls to playlist_get_playing() - * will return -1, and the behavior of drct_play() is unspecified. */ +/* Sets the currently playing playlist. Any information needed to resume + * playback from the previously playing playlist is saved, and playback is + * resumed in the newly set playlist if possible. (See playlist_set_position() + * for a way to prevent this resuming.) */ AUD_VFUNC1 (playlist_set_playing, int, playlist) -/* Returns the number of the playlist from which the last song played was taken, - * or -1 if that cannot be determined. Note that this playlist may not be - * marked active. */ +/* Returns the number of the currently playing playlist, or -1 if there is none. */ AUD_FUNC0 (int, playlist_get_playing) /* Returns the number of a "blank" playlist. The active playlist is returned if @@ -167,7 +162,9 @@ AUD_FUNC3 (char *, playlist_entry_get_title, int, playlist, int, entry, /* Returns three strings (title, artist, and album) describing an entry. The * strings are pooled, and the usual cautions apply. If <fast> is nonzero, * returns a "best guess" based on the entry's filename if metadata for the - * entry has not yet been read. May return NULL for any and all values. */ + * entry has not yet been read. The caller may pass NULL for any values that + * are not needed; NULL may also be returned for any values that are not + * available. */ AUD_VFUNC6 (playlist_entry_describe, int, playlist, int, entry, char * *, title, char * *, artist, char * *, album, bool_t, fast) @@ -178,13 +175,13 @@ AUD_FUNC3 (int, playlist_entry_get_length, int, playlist, int, entry, /* Sets the entry which will be played (if this playlist is selected with * playlist_set_playing()) when drct_play() is called. If a song from this - * playlist is already playing, it will be stopped. If <position> is negative, - * calls to playlist_get_position() will return -1, and the behavior of - * drct_play() is unspecified. */ + * playlist is already playing, it will be stopped. If the playlist has resume + * information set, it will be cleared. It is possible to set a position of -1, + * meaning that no entry is set to be played. */ AUD_VFUNC2 (playlist_set_position, int, playlist, int, position) -/* Returns the number of the entry which was last played from this playlist, or - * -1 if that cannot be determined. */ +/* Returns the number of the entry set to be played (which may or may not be + * currently playing), or -1 if there is none. */ AUD_FUNC1 (int, playlist_get_position, int, playlist) /* Sets whether an entry is selected. */ @@ -206,10 +203,8 @@ AUD_VFUNC2 (playlist_select_all, int, playlist, bool_t, selected) * requested offset. */ AUD_FUNC3 (int, playlist_shift, int, playlist, int, position, int, distance) -/* Removes the selected entries from a playlist. If the last song played is one - * of these entries, playback is stopped. In this case, calls to - * playlist_get_position() will return -1, and the behavior of drct_play() is - * unspecified. */ +/* Removes the selected entries from a playlist. If the currently playing entry + * is among these, playback is stopped. */ AUD_VFUNC1 (playlist_delete_selected, int, playlist) /* Sorts the entries in a playlist based on filename. The callback function diff --git a/src/audacious/playlist-files.c b/src/audacious/playlist-files.c index 74567ce..1da9abe 100644 --- a/src/audacious/playlist-files.c +++ b/src/audacious/playlist-files.c @@ -2,21 +2,19 @@ * playlist-files.c * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/audacious/playlist-new.c b/src/audacious/playlist-new.c index 6407f64..8910937 100644 --- a/src/audacious/playlist-new.c +++ b/src/audacious/playlist-new.c @@ -1,22 +1,20 @@ /* * playlist-new.c - * Copyright 2009-2011 John Lindgren + * Copyright 2009-2012 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <pthread.h> @@ -86,15 +84,6 @@ enum {RESUME_STOP, RESUME_PLAY, RESUME_PAUSE}; LEAVE_RET(ret); \ } while (0) -#define SELECTION_HAS_CHANGED(p, a, c) \ - queue_update (PLAYLIST_UPDATE_SELECTION, p, a, c) - -#define METADATA_HAS_CHANGED(p, a, c) \ - queue_update (PLAYLIST_UPDATE_METADATA, p, a, c) - -#define PLAYLIST_HAS_CHANGED(p, a, c) \ - queue_update (PLAYLIST_UPDATE_STRUCTURE, p, a, c) - typedef struct { int level, before, after; } Update; @@ -126,6 +115,7 @@ typedef struct { int64_t total_length, selected_length; bool_t scanning, scan_ending; Update next_update, last_update; + int resume_state, resume_time; } Playlist; static const char * const default_title = N_("New Playlist"); @@ -144,7 +134,6 @@ static Playlist * active_playlist = NULL; static Playlist * playing_playlist = NULL; static int update_source = 0, update_level; -static int resume_state, resume_time; typedef struct { Playlist * playlist; @@ -212,8 +201,7 @@ static void entry_set_tuple_real (Entry * entry, Tuple * tuple) entry->segmented = TRUE; entry->start = tuple_get_int (tuple, FIELD_SEGMENT_START, NULL); - if (tuple_get_value_type (tuple, FIELD_SEGMENT_END, NULL) == - TUPLE_INT) + if (tuple_get_value_type (tuple, FIELD_SEGMENT_END, NULL) == TUPLE_INT) entry->end = tuple_get_int (tuple, FIELD_SEGMENT_END, NULL); else entry->end = -1; @@ -273,8 +261,7 @@ static void entry_cancel_scan (Entry * entry) } } -static Entry * entry_new (char * filename, Tuple * tuple, - PluginHandle * decoder) +static Entry * entry_new (char * filename, Tuple * tuple, PluginHandle * decoder) { Entry * entry = g_slice_new (Entry); @@ -344,6 +331,8 @@ static Playlist * playlist_new (int id) playlist->selected_length = 0; playlist->scanning = FALSE; playlist->scan_ending = FALSE; + playlist->resume_state = RESUME_STOP; + playlist->resume_time = 0; memset (& playlist->last_update, 0, sizeof (Update)); memset (& playlist->next_update, 0, sizeof (Update)); @@ -704,6 +693,26 @@ static Entry * get_playback_entry (bool_t need_decoder, bool_t need_tuple) } } +static void get_resume_state (int * state, int * time) +{ + if (playback_get_playing ()) + { + * state = playback_get_paused () ? RESUME_PAUSE : RESUME_PLAY; + * time = playback_get_time (); + } + else + { + * state = RESUME_STOP; + * time = 0; + } +} + +static void resume (int state, int time) +{ + if (state == RESUME_PLAY || state == RESUME_PAUSE) + playback_play (time, state == RESUME_PAUSE); +} + void playlist_init (void) { srand (time (NULL)); @@ -778,7 +787,7 @@ void playlist_insert_with_id (int at, int id) index_insert (playlists, at, playlist_new (id)); number_playlists (at, index_count (playlists) - at); - PLAYLIST_HAS_CHANGED (-1, 0, 0); + queue_update (PLAYLIST_UPDATE_STRUCTURE, -1, 0, 0); LEAVE; } @@ -816,12 +825,13 @@ void playlist_reorder (int from, int to, int count) index_free (displaced); - PLAYLIST_HAS_CHANGED (-1, 0, 0); + queue_update (PLAYLIST_UPDATE_STRUCTURE, -1, 0, 0); LEAVE; } void playlist_delete (int playlist_num) { + /* stop playback before locking playlists */ if (playback_get_playing () && playlist_num == playlist_get_playing ()) playback_stop (); @@ -838,12 +848,11 @@ void playlist_delete (int playlist_num) number_playlists (playlist_num, index_count (playlists) - playlist_num); if (playlist == active_playlist) - active_playlist = index_get (playlists, MIN (playlist_num, index_count - (playlists) - 1)); + active_playlist = index_get (playlists, MIN (playlist_num, index_count (playlists) - 1)); if (playlist == playing_playlist) playing_playlist = NULL; - PLAYLIST_HAS_CHANGED (-1, 0, 0); + queue_update (PLAYLIST_UPDATE_STRUCTURE, -1, 0, 0); LEAVE; } @@ -878,7 +887,7 @@ void playlist_set_filename (int playlist_num, const char * filename) playlist->filename = str_get (filename); playlist->modified = TRUE; - METADATA_HAS_CHANGED (-1, 0, 0); + queue_update (PLAYLIST_UPDATE_METADATA, -1, 0, 0); LEAVE; } @@ -903,7 +912,7 @@ void playlist_set_title (int playlist_num, const char * title) playlist->title = str_get (title); playlist->modified = TRUE; - METADATA_HAS_CHANGED (-1, 0, 0); + queue_update (PLAYLIST_UPDATE_METADATA, -1, 0, 0); LEAVE; } @@ -969,10 +978,24 @@ int playlist_get_active (void) void playlist_set_playing (int playlist_num) { - if (playback_get_playing ()) + if (playlist_num == playlist_get_playing ()) + return; + + /* get playback state and stop playback before locking playlists */ + int state, time; + get_resume_state (& state, & time); + + if (state != RESUME_STOP) playback_stop (); ENTER; + + if (playing_playlist) + { + playing_playlist->resume_state = state; + playing_playlist->resume_time = time; + } + DECLARE_PLAYLIST; if (playlist_num < 0) @@ -982,9 +1005,23 @@ void playlist_set_playing (int playlist_num) playing_playlist = playlist; + if (playlist) + { + state = playlist->resume_state; + time = playlist->resume_time; + } + else + { + state = RESUME_STOP; + time = 0; + } + LEAVE; hook_call ("playlist set playing", NULL); + + /* resume playback after unlocking playlists */ + resume (state, time); } int playlist_get_playing (void) @@ -1033,23 +1070,15 @@ int playlist_get_temporary (void) return list; } -/* If we are already at the song or it is already at the top of the shuffle - * list, we let it be. Otherwise, we move it to the top. */ -static void set_position (Playlist * playlist, Entry * entry) +static void set_position (Playlist * playlist, Entry * entry, bool_t update_shuffle) { - if (entry == playlist->position) - return; - playlist->position = entry; + playlist->resume_state = RESUME_STOP; + playlist->resume_time = 0; - if (! entry) - return; - - if (! entry->shuffle_num || entry->shuffle_num != playlist->last_shuffle_num) - { - playlist->last_shuffle_num ++; - entry->shuffle_num = playlist->last_shuffle_num; - } + /* move entry to top of shuffle list */ + if (entry && update_shuffle) + entry->shuffle_num = ++ playlist->last_shuffle_num; } int playlist_entry_count (int playlist_num) @@ -1106,12 +1135,13 @@ void playlist_entry_insert_batch_raw (int playlist_num, int at, playlist->total_length += entry->length; } - PLAYLIST_HAS_CHANGED (playlist->number, at, number); + queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, at, number); LEAVE; } void playlist_entry_delete (int playlist_num, int at, int number) { + /* stop playback before locking playlists */ if (playback_get_playing () && playlist_num == playlist_get_playing () && playlist_get_position (playlist_num) >= at && playlist_get_position (playlist_num) < at + number) @@ -1130,7 +1160,7 @@ void playlist_entry_delete (int playlist_num, int at, int number) if (playlist->position && playlist->position->number >= at && playlist->position->number < at + number) - set_position (playlist, NULL); + set_position (playlist, NULL, FALSE); for (int count = 0; count < number; count ++) { @@ -1152,7 +1182,7 @@ void playlist_entry_delete (int playlist_num, int at, int number) index_delete (playlist->entries, at, number); number_entries (playlist, at, entries - at - number); - PLAYLIST_HAS_CHANGED (playlist->number, at, 0); + queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, at, 0); LEAVE; } @@ -1206,9 +1236,13 @@ void playlist_entry_describe (int playlist_num, int entry_num, ENTER; Entry * entry = get_entry (playlist_num, entry_num, FALSE, ! fast); - * title = (entry && entry->title) ? str_ref (entry->title) : NULL; - * artist = (entry && entry->artist) ? str_ref (entry->artist) : NULL; - * album = (entry && entry->album) ? str_ref (entry->album) : NULL; + + if (title) + * title = (entry && entry->title) ? str_ref (entry->title) : NULL; + if (artist) + * artist = (entry && entry->artist) ? str_ref (entry->artist) : NULL; + if (album) + * album = (entry && entry->album) ? str_ref (entry->album) : NULL; LEAVE; } @@ -1225,6 +1259,7 @@ int playlist_entry_get_length (int playlist_num, int entry_num, bool_t fast) void playlist_set_position (int playlist_num, int entry_num) { + /* stop playback before locking playlists */ if (playback_get_playing () && playlist_num == playlist_get_playing ()) playback_stop (); @@ -1239,7 +1274,7 @@ void playlist_set_position (int playlist_num, int entry_num) else LOOKUP_PLAYLIST_ENTRY; - set_position (playlist, entry); + set_position (playlist, entry, TRUE); LEAVE; hook_call ("playlist position", GINT_TO_POINTER (playlist_num)); @@ -1279,7 +1314,7 @@ void playlist_entry_set_selected (int playlist_num, int entry_num, playlist->selected_length -= entry->length; } - SELECTION_HAS_CHANGED (playlist->number, entry_num, 1); + queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, entry_num, 1); LEAVE; } @@ -1338,7 +1373,7 @@ void playlist_select_all (int playlist_num, bool_t selected) } if (first < entries) - SELECTION_HAS_CHANGED (playlist->number, first, last + 1 - first); + queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, first, last + 1 - first); LEAVE; } @@ -1416,13 +1451,14 @@ int playlist_shift (int playlist_num, int entry_num, int distance) index_copy_set (temp, 0, playlist->entries, top, bottom - top); number_entries (playlist, top, bottom - top); - PLAYLIST_HAS_CHANGED (playlist->number, top, bottom - top); + queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, top, bottom - top); LEAVE_RET (shift); } void playlist_delete_selected (int playlist_num) { + /* stop playback before locking playlists */ if (playback_get_playing () && playlist_num == playlist_get_playing () && playlist_get_position (playlist_num) >= 0 && playlist_entry_get_selected (playlist_num, playlist_get_position (playlist_num))) @@ -1441,7 +1477,7 @@ void playlist_delete_selected (int playlist_num) index_allocate (others, entries - playlist->selected_count); if (playlist->position && playlist->position->selected) - set_position (playlist, NULL); + set_position (playlist, NULL, FALSE); int before = 0, after = 0; bool_t found = FALSE; @@ -1479,8 +1515,8 @@ void playlist_delete_selected (int playlist_num) playlist->selected_length = 0; number_entries (playlist, before, index_count (playlist->entries) - before); - PLAYLIST_HAS_CHANGED (playlist->number, before, index_count - (playlist->entries) - after - before); + queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, before, + index_count (playlist->entries) - after - before); LEAVE; } @@ -1502,7 +1538,7 @@ void playlist_reverse (int playlist_num) playlist->entries = reversed; number_entries (playlist, 0, entries); - PLAYLIST_HAS_CHANGED (playlist->number, 0, entries); + queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, entries); LEAVE; } @@ -1524,50 +1560,36 @@ void playlist_randomize (int playlist_num) } number_entries (playlist, 0, entries); - PLAYLIST_HAS_CHANGED (playlist->number, 0, entries); + queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, entries); LEAVE; } -static int filename_compare (const void * _a, const void * _b, void * compare) -{ - const Entry * a = _a, * b = _b; +enum { + COMPARE_TYPE_FILENAME, + COMPARE_TYPE_TUPLE, + COMPARE_TYPE_TITLE}; - int diff = ((int (*) (const char * a, const char * b)) compare) - (a->filename, b->filename); +typedef int (* CompareFunc) (const void * a, const void * b); - if (diff) - return diff; - - /* preserve order of "equal" entries */ - return a->number - b->number; -} +typedef struct { + int type; + CompareFunc func; +} CompareData; -static int tuple_compare (const void * _a, const void * _b, void * compare) +static int compare_cb (const void * _a, const void * _b, void * _data) { const Entry * a = _a, * b = _b; + CompareData * data = _data; - if (! a->tuple) - return b->tuple ? -1 : 0; - if (! b->tuple) - return 1; - - int diff = ((int (*) (const Tuple * a, const Tuple * b)) compare) - (a->tuple, b->tuple); - - if (diff) - return diff; - - /* preserve order of "equal" entries */ - return a->number - b->number; -} - -static int title_compare (const void * _a, const void * _b, void * compare) -{ - const Entry * a = _a, * b = _b; + int diff = 0; - int diff = ((int (*) (const char * a, const char * b)) compare) - (a->formatted ? a->formatted : a->filename, - b->formatted ? b->formatted : b->filename); + if (data->type == COMPARE_TYPE_FILENAME) + diff = data->func (a->filename, b->filename); + else if (data->type == COMPARE_TYPE_TUPLE) + diff = data->func (a->tuple, b->tuple); + else if (data->type == COMPARE_TYPE_TITLE) + diff = data->func (a->formatted ? a->formatted : a->filename, + b->formatted ? b->formatted : b->filename); if (diff) return diff; @@ -1576,17 +1598,15 @@ static int title_compare (const void * _a, const void * _b, void * compare) return a->number - b->number; } -static void sort (Playlist * playlist, int (* compare) (const void * a, - const void * b, void * inner), void * inner) +static void sort (Playlist * playlist, CompareData * data) { - index_sort_with_data (playlist->entries, compare, inner); + index_sort_with_data (playlist->entries, compare_cb, data); number_entries (playlist, 0, index_count (playlist->entries)); - PLAYLIST_HAS_CHANGED (playlist->number, 0, index_count (playlist->entries)); + queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, index_count (playlist->entries)); } -static void sort_selected (Playlist * playlist, int (* compare) (const void * - a, const void * b, void * inner), void * inner) +static void sort_selected (Playlist * playlist, CompareData * data) { int entries = index_count (playlist->entries); @@ -1600,7 +1620,7 @@ static void sort_selected (Playlist * playlist, int (* compare) (const void * index_append (selected, entry); } - index_sort_with_data (selected, compare, inner); + index_sort_with_data (selected, compare_cb, data); int count2 = 0; for (int count = 0; count < entries; count++) @@ -1613,7 +1633,7 @@ static void sort_selected (Playlist * playlist, int (* compare) (const void * index_free (selected); number_entries (playlist, 0, entries); - PLAYLIST_HAS_CHANGED (playlist->number, 0, entries); + queue_update (PLAYLIST_UPDATE_STRUCTURE, playlist->number, 0, entries); } static bool_t entries_are_scanned (Playlist * playlist, bool_t selected) @@ -1643,7 +1663,8 @@ void playlist_sort_by_filename (int playlist_num, int (* compare) DECLARE_PLAYLIST; LOOKUP_PLAYLIST; - sort (playlist, filename_compare, (void *) compare); + CompareData data = {COMPARE_TYPE_FILENAME, (CompareFunc) compare}; + sort (playlist, & data); LEAVE; } @@ -1655,8 +1676,9 @@ void playlist_sort_by_tuple (int playlist_num, int (* compare) DECLARE_PLAYLIST; LOOKUP_PLAYLIST; + CompareData data = {COMPARE_TYPE_TUPLE, (CompareFunc) compare}; if (entries_are_scanned (playlist, FALSE)) - sort (playlist, tuple_compare, (void *) compare); + sort (playlist, & data); LEAVE; } @@ -1668,8 +1690,9 @@ void playlist_sort_by_title (int playlist_num, int (* compare) (const char * DECLARE_PLAYLIST; LOOKUP_PLAYLIST; + CompareData data = {COMPARE_TYPE_TITLE, (CompareFunc) compare}; if (entries_are_scanned (playlist, FALSE)) - sort (playlist, title_compare, (void *) compare); + sort (playlist, & data); LEAVE; } @@ -1681,7 +1704,8 @@ void playlist_sort_selected_by_filename (int playlist_num, int (* compare) DECLARE_PLAYLIST; LOOKUP_PLAYLIST; - sort_selected (playlist, filename_compare, (void *) compare); + CompareData data = {COMPARE_TYPE_FILENAME, (CompareFunc) compare}; + sort_selected (playlist, & data); LEAVE; } @@ -1693,8 +1717,9 @@ void playlist_sort_selected_by_tuple (int playlist_num, int (* compare) DECLARE_PLAYLIST; LOOKUP_PLAYLIST; + CompareData data = {COMPARE_TYPE_TUPLE, (CompareFunc) compare}; if (entries_are_scanned (playlist, TRUE)) - sort_selected (playlist, tuple_compare, (void *) compare); + sort_selected (playlist, & data); LEAVE; } @@ -1706,8 +1731,9 @@ void playlist_sort_selected_by_title (int playlist_num, int (* compare) DECLARE_PLAYLIST; LOOKUP_PLAYLIST; + CompareData data = {COMPARE_TYPE_TITLE, (CompareFunc) compare}; if (entries_are_scanned (playlist, TRUE)) - sort (playlist, title_compare, (void *) compare); + sort (playlist, & data); LEAVE; } @@ -1732,7 +1758,7 @@ void playlist_reformat_titles (void) entry->formatted = entry->tuple ? title_from_tuple (entry->tuple) : NULL; } - METADATA_HAS_CHANGED (playlist_num, 0, entries); + queue_update (PLAYLIST_UPDATE_METADATA, playlist_num, 0, entries); } LEAVE; @@ -1771,7 +1797,7 @@ static void playlist_rescan_real (int playlist_num, bool_t selected) } } - METADATA_HAS_CHANGED (playlist->number, 0, entries); + queue_update (PLAYLIST_UPDATE_METADATA, playlist->number, 0, entries); LEAVE; } @@ -1805,7 +1831,7 @@ void playlist_rescan_file (const char * filename) entry_set_tuple (playlist, entry, NULL); entry->failed = FALSE; - METADATA_HAS_CHANGED (playlist_num, entry_num, 1); + queue_update (PLAYLIST_UPDATE_METADATA, playlist_num, entry_num, 1); } } } @@ -1862,7 +1888,7 @@ void playlist_queue_insert (int playlist_num, int at, int entry_num) entry->queued = TRUE; - SELECTION_HAS_CHANGED (playlist->number, entry_num, 1); + queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, entry_num, 1); LEAVE; } @@ -1893,7 +1919,7 @@ void playlist_queue_insert_selected (int playlist_num, int at) } if (first < entries) - SELECTION_HAS_CHANGED (playlist->number, first, last + 1 - first); + queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, first, last + 1 - first); LEAVE; } @@ -1939,8 +1965,7 @@ void playlist_queue_delete (int playlist_num, int at, int number) first = MIN (first, entry->number); last = entry->number; - playlist->queued = g_list_delete_link (playlist->queued, - playlist->queued); + playlist->queued = g_list_delete_link (playlist->queued, playlist->queued); } } else @@ -1956,14 +1981,13 @@ void playlist_queue_delete (int playlist_num, int at, int number) first = MIN (first, entry->number); last = entry->number; - playlist->queued = g_list_delete_link (playlist->queued, - anchor->next); + playlist->queued = g_list_delete_link (playlist->queued, anchor->next); } } DONE: if (first < entries) - SELECTION_HAS_CHANGED (playlist->number, first, last + 1 - first); + queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, first, last + 1 - first); LEAVE; } @@ -1994,7 +2018,7 @@ void playlist_queue_delete_selected (int playlist_num) } if (first < entries) - SELECTION_HAS_CHANGED (playlist->number, first, last + 1 - first); + queue_update (PLAYLIST_UPDATE_SELECTION, playlist->number, first, last + 1 - first); LEAVE; } @@ -2017,12 +2041,13 @@ static bool_t shuffle_prev (Playlist * playlist) if (! found) return FALSE; - playlist->position = found; + set_position (playlist, found, FALSE); return TRUE; } bool_t playlist_prev_song (int playlist_num) { + /* stop playback before locking playlists */ if (playback_get_playing () && playlist_num == playlist_get_playing ()) playback_stop (); @@ -2041,7 +2066,7 @@ bool_t playlist_prev_song (int playlist_num) LEAVE_RET (FALSE); set_position (playlist, index_get (playlist->entries, - playlist->position->number - 1)); + playlist->position->number - 1), TRUE); } LEAVE; @@ -2069,7 +2094,7 @@ static bool_t shuffle_next (Playlist * playlist) if (found) { - playlist->position = found; + set_position (playlist, found, FALSE); return TRUE; } @@ -2086,7 +2111,7 @@ static bool_t shuffle_next (Playlist * playlist) { if (! choice) { - set_position (playlist, entry); + set_position (playlist, entry, TRUE); return TRUE; } @@ -2110,6 +2135,7 @@ static void shuffle_reset (Playlist * playlist) bool_t playlist_next_song (int playlist_num, bool_t repeat) { + /* stop playback before locking playlists */ if (playback_get_playing () && playlist_num == playlist_get_playing ()) playback_stop (); @@ -2124,7 +2150,7 @@ bool_t playlist_next_song (int playlist_num, bool_t repeat) if (playlist->queued) { - set_position (playlist, playlist->queued->data); + set_position (playlist, playlist->queued->data, TRUE); playlist->queued = g_list_remove (playlist->queued, playlist->position); playlist->position->queued = FALSE; } @@ -2144,17 +2170,17 @@ bool_t playlist_next_song (int playlist_num, bool_t repeat) else { if (! playlist->position) - set_position (playlist, index_get (playlist->entries, 0)); + set_position (playlist, index_get (playlist->entries, 0), TRUE); else if (playlist->position->number == entries - 1) { if (! repeat) LEAVE_RET (FALSE); - set_position (playlist, index_get (playlist->entries, 0)); + set_position (playlist, index_get (playlist->entries, 0), TRUE); } else set_position (playlist, index_get (playlist->entries, - playlist->position->number + 1)); + playlist->position->number + 1), TRUE); } LEAVE; @@ -2201,8 +2227,7 @@ char * playback_entry_get_title (void) ENTER; Entry * entry = get_playback_entry (FALSE, TRUE); - char * title = entry ? str_ref (entry->formatted ? entry->formatted : - entry->title) : NULL; + char * title = entry ? str_ref (entry->formatted ? entry->formatted : entry->title) : NULL; LEAVE_RET (title); } @@ -2227,7 +2252,7 @@ void playback_entry_set_tuple (Tuple * tuple) entry_cancel_scan (entry); entry_set_tuple (playing_playlist, entry, tuple); - METADATA_HAS_CHANGED (playing_playlist->number, entry->number, 1); + queue_update (PLAYLIST_UPDATE_METADATA, playing_playlist->number, entry->number, 1); LEAVE; } @@ -2253,6 +2278,10 @@ int playback_entry_get_end_time (void) void playlist_save_state (void) { + /* get playback state before locking playlists */ + int state, time; + get_resume_state (& state, & time); + ENTER; char * path = g_strdup_printf ("%s/" STATE_FILE, get_path (AUD_PATH_USER_DIR)); @@ -2261,13 +2290,6 @@ void playlist_save_state (void) if (! handle) LEAVE_RET_VOID; - resume_state = playback_get_playing () ? (playback_get_paused () ? - RESUME_PAUSE : RESUME_PLAY) : RESUME_STOP; - resume_time = playback_get_playing () ? playback_get_time () : 0; - - fprintf (handle, "resume-state %d\n", resume_state); - fprintf (handle, "resume-time %d\n", resume_time); - fprintf (handle, "active %d\n", active_playlist ? active_playlist->number : -1); fprintf (handle, "playing %d\n", playing_playlist ? playing_playlist->number : -1); @@ -2281,8 +2303,16 @@ void playlist_save_state (void) if (playlist->filename) fprintf (handle, "filename %s\n", playlist->filename); - fprintf (handle, "position %d\n", playlist->position ? - playlist->position->number : -1); + fprintf (handle, "position %d\n", playlist->position ? playlist->position->number : -1); + + if (playlist == playing_playlist) + { + playlist->resume_state = state; + playlist->resume_time = time; + } + + fprintf (handle, "resume-state %d\n", playlist->resume_state); + fprintf (handle, "resume-time %d\n", playlist->resume_time); } fclose (handle); @@ -2313,8 +2343,7 @@ static void parse_next (FILE * handle) static bool_t parse_integer (const char * key, int * value) { - return (parse_value && ! strcmp (parse_key, key) && sscanf (parse_value, - "%d", value) == 1); + return (parse_value && ! strcmp (parse_key, key) && sscanf (parse_value, "%d", value) == 1); } static char * parse_string (const char * key) @@ -2335,11 +2364,6 @@ void playlist_load_state (void) parse_next (handle); - if (parse_integer ("resume-state", & resume_state)) - parse_next (handle); - if (parse_integer ("resume-time", & resume_time)) - parse_next (handle); - if (parse_integer ("active", & playlist_num)) { if (! (active_playlist = lookup_playlist (playlist_num))) @@ -2373,7 +2397,12 @@ void playlist_load_state (void) parse_next (handle); if (position >= 0 && position < entries) - set_position (playlist, index_get (playlist->entries, position)); + set_position (playlist, index_get (playlist->entries, position), TRUE); + + if (parse_integer ("resume-state", & playlist->resume_state)) + parse_next (handle); + if (parse_integer ("resume-time", & playlist->resume_time)) + parse_next (handle); } fclose (handle); @@ -2400,6 +2429,21 @@ void playlist_load_state (void) void playlist_resume (void) { - if (resume_state == RESUME_PLAY || resume_state == RESUME_PAUSE) - playback_play (resume_time, resume_state == RESUME_PAUSE); + int state = RESUME_STOP, time = 0; + + ENTER; + + if (playing_playlist) + { + state = playing_playlist->resume_state; + time = playing_playlist->resume_time; + } + + LEAVE; + + /* resume playback after unlocking playlists */ + if (state == RESUME_PLAY && ! get_bool (NULL, "resume_playback_on_startup")) + state = RESUME_PAUSE; + + resume (state, time); } diff --git a/src/audacious/playlist-utils.c b/src/audacious/playlist-utils.c index 66a879f..6bde4e3 100644 --- a/src/audacious/playlist-utils.c +++ b/src/audacious/playlist-utils.c @@ -2,21 +2,19 @@ * playlist-utils.c * Copyright 2009-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <dirent.h> @@ -473,8 +471,8 @@ void save_playlists (bool_t exiting) { save_playlists_real (); - /* on exit, save resume time if resume feature is enabled */ - if (state_changed || (exiting && get_bool (NULL, "resume_playback_on_startup"))) + /* on exit, save resume states */ + if (state_changed || exiting) { playlist_save_state (); state_changed = FALSE; diff --git a/src/audacious/playlist.h b/src/audacious/playlist.h index 52cc3b3..d43bbcd 100644 --- a/src/audacious/playlist.h +++ b/src/audacious/playlist.h @@ -1,22 +1,20 @@ /* * playlist.h - * Copyright 2010 John Lindgren + * Copyright 2010-2012 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_PLAYLIST_H diff --git a/src/audacious/plugin-init.c b/src/audacious/plugin-init.c index dd1e692..1755467 100644 --- a/src/audacious/plugin-init.c +++ b/src/audacious/plugin-init.c @@ -2,21 +2,19 @@ * plugin-init.c * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <errno.h> @@ -47,7 +45,7 @@ static void dummy_plugin_stop (PluginHandle * p) static const struct { const char * name; - bool_t is_managed, is_single; + bool_t is_single; union { struct { @@ -62,33 +60,27 @@ static const struct { } s; } u; } table[PLUGIN_TYPES] = { - [PLUGIN_TYPE_TRANSPORT] = {"transport", TRUE, FALSE, .u.m = - {dummy_plugin_start, dummy_plugin_stop}}, - [PLUGIN_TYPE_PLAYLIST] = {"playlist", TRUE, FALSE, .u.m = {dummy_plugin_start, - dummy_plugin_stop}}, - [PLUGIN_TYPE_INPUT] = {"input", TRUE, FALSE, .u.m = {dummy_plugin_start, - dummy_plugin_stop}}, - [PLUGIN_TYPE_EFFECT] = {"effect", TRUE, FALSE, .u.m = {effect_plugin_start, - effect_plugin_stop}}, - [PLUGIN_TYPE_OUTPUT] = {"output", TRUE, TRUE, .u.s = {output_plugin_probe, + [PLUGIN_TYPE_TRANSPORT] = {"transport", FALSE, .u.m = {dummy_plugin_start, dummy_plugin_stop}}, + [PLUGIN_TYPE_PLAYLIST] = {"playlist", FALSE, .u.m = {dummy_plugin_start, dummy_plugin_stop}}, + [PLUGIN_TYPE_INPUT] = {"input", FALSE, .u.m = {dummy_plugin_start, dummy_plugin_stop}}, + [PLUGIN_TYPE_EFFECT] = {"effect", FALSE, .u.m = {effect_plugin_start, effect_plugin_stop}}, + [PLUGIN_TYPE_OUTPUT] = {"output", TRUE, .u.s = {output_plugin_probe, output_plugin_get_current, output_plugin_set_current}}, - [PLUGIN_TYPE_VIS] = {"visualization", TRUE, FALSE, .u.m = {vis_plugin_start, - vis_plugin_stop}}, - [PLUGIN_TYPE_GENERAL] = {"general", TRUE, FALSE, .u.m = {general_plugin_start, - general_plugin_stop}}, - [PLUGIN_TYPE_IFACE] = {"interface", TRUE, TRUE, .u.s = {iface_plugin_probe, + [PLUGIN_TYPE_VIS] = {"visualization", FALSE, .u.m = {vis_plugin_start, vis_plugin_stop}}, + [PLUGIN_TYPE_GENERAL] = {"general", FALSE, .u.m = {general_plugin_start, general_plugin_stop}}, + [PLUGIN_TYPE_IFACE] = {"interface", TRUE, .u.s = {iface_plugin_probe, iface_plugin_get_current, iface_plugin_set_current}}}; -static bool_t find_enabled_cb (PluginHandle * p, PluginHandle * * pp) +static bool_t find_enabled_cb (PluginHandle * p, void * pp) { - * pp = p; + * (PluginHandle * *) pp = p; return FALSE; } static PluginHandle * find_enabled (int type) { PluginHandle * p = NULL; - plugin_for_enabled (type, (PluginForEachFunc) find_enabled_cb, & p); + plugin_for_enabled (type, find_enabled_cb, & p); return p; } @@ -142,16 +134,13 @@ static bool_t start_multi_cb (PluginHandle * p, void * type) static void start_plugins (int type) { - if (! table[type].is_managed) - return; if (headless && type == PLUGIN_TYPE_IFACE) return; if (table[type].is_single) start_single (type); else - plugin_for_enabled (type, (PluginForEachFunc) start_multi_cb, - GINT_TO_POINTER (type)); + plugin_for_enabled (type, start_multi_cb, GINT_TO_POINTER (type)); } static VFSConstructor * lookup_transport (const char * scheme) @@ -179,6 +168,12 @@ void start_plugins_two (void) start_plugins (i); } +static bool_t misc_cleanup_cb (PluginHandle * p, void * unused) +{ + plugin_misc_cleanup (p); + return TRUE; +} + static bool_t stop_multi_cb (PluginHandle * p, void * type) { AUDDBG ("Shutting down %s.\n", plugin_get_name (p)); @@ -188,11 +183,11 @@ static bool_t stop_multi_cb (PluginHandle * p, void * type) static void stop_plugins (int type) { - if (! table[type].is_managed) - return; if (headless && type == PLUGIN_TYPE_IFACE) return; + plugin_for_enabled (type, misc_cleanup_cb, GINT_TO_POINTER (type)); + if (table[type].is_single) { AUDDBG ("Shutting down %s.\n", plugin_get_name @@ -200,8 +195,7 @@ static void stop_plugins (int type) table[type].u.s.set_current (NULL); } else - plugin_for_enabled (type, (PluginForEachFunc) stop_multi_cb, - GINT_TO_POINTER (type)); + plugin_for_enabled (type, stop_multi_cb, GINT_TO_POINTER (type)); } void stop_plugins_two (void) @@ -221,7 +215,7 @@ void stop_plugins_one (void) PluginHandle * plugin_get_current (int type) { - g_return_val_if_fail (table[type].is_managed && table[type].is_single, NULL); + g_return_val_if_fail (table[type].is_single, NULL); return table[type].u.s.get_current (); } @@ -273,14 +267,12 @@ static bool_t enable_multi (int type, PluginHandle * p, bool_t enable) bool_t plugin_enable (PluginHandle * plugin, bool_t enable) { if (! enable == ! plugin_get_enabled (plugin)) - { - AUDDBG ("%s is already %sabled.\n", plugin_get_name (plugin), enable ? - "en" : "dis"); return TRUE; - } + + if (! enable) + plugin_misc_cleanup (plugin); int type = plugin_get_type (plugin); - g_return_val_if_fail (table[type].is_managed, FALSE); if (table[type].is_single) { @@ -314,3 +306,27 @@ int plugin_send_message (PluginHandle * plugin, const char * code, const void * return header->take_message (code, data, size); } + +void plugin_do_about (PluginHandle * plugin) +{ + g_return_if_fail (plugin_get_enabled (plugin)); + Plugin * header = plugin_get_header (plugin); + g_return_if_fail (header); + + if (PLUGIN_HAS_FUNC (header, about)) + header->about (); + else if (PLUGIN_HAS_FUNC (header, about_text)) + plugin_make_about_window (plugin); +} + +void plugin_do_configure (PluginHandle * plugin) +{ + g_return_if_fail (plugin_get_enabled (plugin)); + Plugin * header = plugin_get_header (plugin); + g_return_if_fail (header); + + if (PLUGIN_HAS_FUNC (header, configure)) + header->configure (); + else if (PLUGIN_HAS_FUNC (header, prefs)) + plugin_make_config_window (plugin); +} diff --git a/src/audacious/plugin-preferences.c b/src/audacious/plugin-preferences.c new file mode 100644 index 0000000..f995b63 --- /dev/null +++ b/src/audacious/plugin-preferences.c @@ -0,0 +1,119 @@ +/* + * plugin-preferences.c + * Copyright 2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <libaudgui/libaudgui-gtk.h> + +#include "config.h" +#include "i18n.h" +#include "misc.h" +#include "plugin.h" +#include "plugins.h" +#include "preferences.h" +#include "ui_preferences.h" + +void plugin_make_about_window (PluginHandle * plugin) +{ + PluginMiscData * misc = plugin_get_misc_data (plugin); + Plugin * header = plugin_get_header (plugin); + + if (misc->about_window) + { + gtk_window_present ((GtkWindow *) misc->about_window); + return; + } + + const char * name = header->name; + const char * text = header->about_text; + + if (PLUGIN_HAS_FUNC (header, domain)) + { + name = dgettext (header->domain, name); + text = dgettext (header->domain, text); + } + + char * title = g_strdup_printf (_("About %s"), name); + audgui_simple_message ((GtkWidget * *) & misc->about_window, GTK_MESSAGE_INFO, title, text); + g_free (title); +} + +static void response_cb (GtkWidget * window, int response, const PluginPreferences * p) +{ + if (response == GTK_RESPONSE_OK && p->apply) + p->apply (); + + gtk_widget_destroy (window); +} + +static void destroy_cb (GtkWidget * window, const PluginPreferences * p) +{ + if (p->cleanup) + p->cleanup (); +} + +void plugin_make_config_window (PluginHandle * plugin) +{ + PluginMiscData * misc = plugin_get_misc_data (plugin); + Plugin * header = plugin_get_header (plugin); + const PluginPreferences * p = header->prefs; + + if (misc->config_window) + { + gtk_window_present ((GtkWindow *) misc->config_window); + return; + } + + if (p->init) + p->init (); + + const char * name = header->name; + if (PLUGIN_HAS_FUNC (header, domain)) + name = dgettext (header->domain, header->name); + + char * title = g_strdup_printf (_("%s Settings"), name); + + GtkWidget * window = p->apply ? gtk_dialog_new_with_buttons (title, NULL, 0, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL) + : gtk_dialog_new_with_buttons (title, NULL, 0, GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE, NULL); + + g_free (title); + + GtkWidget * content = gtk_dialog_get_content_area ((GtkDialog *) window); + GtkWidget * box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + create_widgets_with_domain (box, p->widgets, p->n_widgets, header->domain); + gtk_box_pack_start ((GtkBox *) content, box, TRUE, TRUE, 0); + + g_signal_connect (window, "response", (GCallback) response_cb, (void *) p); + g_signal_connect (window, "destroy", (GCallback) destroy_cb, (void *) p); + + misc->config_window = window; + g_signal_connect (window, "destroy", (GCallback) gtk_widget_destroyed, & misc->config_window); + + gtk_widget_show_all (window); +} + +void plugin_misc_cleanup (PluginHandle * plugin) +{ + PluginMiscData * misc = plugin_get_misc_data (plugin); + + if (misc->about_window) + gtk_widget_destroy (misc->about_window); + if (misc->config_window) + gtk_widget_destroy (misc->config_window); +} diff --git a/src/audacious/plugin-registry.c b/src/audacious/plugin-registry.c index 7baa2e8..0cbd909 100644 --- a/src/audacious/plugin-registry.c +++ b/src/audacious/plugin-registry.c @@ -2,21 +2,19 @@ * plugin-registry.c * Copyright 2009-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /* While the registry is being built (during early startup) or destroyed (during @@ -34,6 +32,7 @@ #include <libaudcore/audstrings.h> #include "debug.h" +#include "i18n.h" #include "interface.h" #include "misc.h" #include "plugin.h" @@ -41,7 +40,7 @@ #include "util.h" #define FILENAME "plugin-registry" -#define FORMAT 6 +#define FORMAT 8 typedef struct { GList * schemes; @@ -61,10 +60,11 @@ struct PluginHandle { bool_t confirmed, loaded; int timestamp, type; Plugin * header; - char * name; + char * name, * domain; int priority; bool_t has_about, has_configure, enabled; GList * watches; + PluginMiscData misc; union { TransportPluginData t; @@ -109,12 +109,15 @@ static PluginHandle * plugin_new (char * path, bool_t confirmed, bool_t plugin->type = type; plugin->header = header; plugin->name = NULL; + plugin->domain = NULL; plugin->priority = 0; plugin->has_about = FALSE; plugin->has_configure = FALSE; plugin->enabled = FALSE; plugin->watches = NULL; + memset (& plugin->misc, 0, sizeof (PluginMiscData)); + if (type == PLUGIN_TYPE_TRANSPORT) { plugin->enabled = TRUE; @@ -167,6 +170,7 @@ static void plugin_free (PluginHandle * plugin) g_free (plugin->path); g_free (plugin->name); + g_free (plugin->domain); g_free (plugin); } @@ -210,6 +214,10 @@ static void plugin_save (PluginHandle * plugin, FILE * handle) fprintf (handle, "%s %s\n", plugin_type_names[plugin->type], plugin->path); fprintf (handle, "stamp %d\n", plugin->timestamp); fprintf (handle, "name %s\n", plugin->name); + + if (plugin->domain) + fprintf (handle, "domain %s\n", plugin->domain); + fprintf (handle, "priority %d\n", plugin->priority); fprintf (handle, "about %d\n", plugin->has_about); fprintf (handle, "config %d\n", plugin->has_configure); @@ -343,6 +351,8 @@ FOUND: if ((plugin->name = parse_string ("name"))) parse_next (handle); + if ((plugin->domain = parse_string ("domain"))) + parse_next (handle); if (parse_integer ("priority", & plugin->priority)) parse_next (handle); if (parse_integer ("about", & plugin->has_about)) @@ -406,7 +416,7 @@ int plugin_compare (PluginHandle * a, PluginHandle * b) return 1; int diff; - if ((diff = string_compare (a->name, b->name))) + if ((diff = string_compare (dgettext (a->domain, a->name), dgettext (b->domain, b->name)))) return diff; return string_compare (a->path, b->path); @@ -507,10 +517,11 @@ void plugin_register_loaded (const char * path, Plugin * header) } g_free (plugin->name); + g_free (plugin->domain); plugin->name = g_strdup (header->name); - plugin->has_about = PLUGIN_HAS_FUNC (header, about); - plugin->has_configure = PLUGIN_HAS_FUNC (header, configure) || - PLUGIN_HAS_FUNC (header, settings); + plugin->domain = PLUGIN_HAS_FUNC (header, domain) ? g_strdup (header->domain) : NULL; + plugin->has_about = PLUGIN_HAS_FUNC (header, about) || PLUGIN_HAS_FUNC (header, about_text); + plugin->has_configure = PLUGIN_HAS_FUNC (header, configure) || PLUGIN_HAS_FUNC (header, prefs); if (header->type == PLUGIN_TYPE_TRANSPORT) { @@ -607,6 +618,11 @@ const void * plugin_get_header (PluginHandle * plugin) return plugin->header; } +const void * plugin_get_header_no_load (PluginHandle * plugin) +{ + return plugin->header; +} + static int plugin_by_header_cb (PluginHandle * plugin, const void * header) { return (plugin->header == header) ? 0 : -1; @@ -632,7 +648,7 @@ void plugin_for_each (int type, PluginForEachFunc func, void * data) const char * plugin_get_name (PluginHandle * plugin) { - return plugin->name; + return dgettext (plugin->domain, plugin->name); } bool_t plugin_has_about (PluginHandle * plugin) @@ -719,6 +735,11 @@ void plugin_remove_watch (PluginHandle * plugin, PluginForEachFunc func, void * } } +PluginMiscData * plugin_get_misc_data (PluginHandle * plugin) +{ + return & plugin->misc; +} + typedef struct { const char * scheme; PluginHandle * plugin; diff --git a/src/audacious/plugin-view.c b/src/audacious/plugin-view.c index 4fbdeaa..7d3a8af 100644 --- a/src/audacious/plugin-view.c +++ b/src/audacious/plugin-view.c @@ -2,21 +2,19 @@ * plugin-view.c * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <gtk/gtk.h> @@ -57,14 +55,6 @@ static PluginHandle * get_selected_plugin (GtkTreeView * tree) return n == NULL ? NULL : n->p; } -static Plugin * get_selected_header (GtkTreeView * tree) -{ - PluginHandle * p = get_selected_plugin (tree); - g_return_val_if_fail (p != NULL, NULL); - g_return_val_if_fail (plugin_get_enabled (p), NULL); - return plugin_get_header (p); -} - static void do_enable (GtkCellRendererToggle * cell, const char * path_str, GtkTreeModel * model) { @@ -204,22 +194,16 @@ static void button_update (GtkTreeView * tree, GtkWidget * b) static void do_config (GtkTreeView * tree) { - Plugin * header = get_selected_header (tree); - g_return_if_fail (header != NULL); - - if (header->configure != NULL) - header->configure (); - else if (header->settings != NULL) - plugin_preferences_show (header->settings); + PluginHandle * plugin = get_selected_plugin (tree); + g_return_if_fail (plugin != NULL); + plugin_do_configure (plugin); } static void do_about (GtkTreeView * tree) { - Plugin * header = get_selected_header (tree); - g_return_if_fail (header != NULL); - - if (header->about != NULL) - header->about (); + PluginHandle * plugin = get_selected_plugin (tree); + g_return_if_fail (plugin != NULL); + plugin_do_about (plugin); } static void button_destroy (GtkWidget * b) @@ -235,7 +219,7 @@ static void button_destroy (GtkWidget * b) GtkWidget * plugin_view_new (int type) { - GtkWidget * vbox = gtk_vbox_new (FALSE, 6); + GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_set_border_width ((GtkContainer *) vbox, 6); GtkWidget * scrolled = gtk_scrolled_window_new (NULL, NULL); @@ -252,7 +236,7 @@ GtkWidget * plugin_view_new (int type) (type)); g_signal_connect (tree, "destroy", (GCallback) list_destroy, NULL); - GtkWidget * hbox = gtk_hbox_new (FALSE, 6); + GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0); GtkWidget * config = gtk_button_new_from_stock (GTK_STOCK_PREFERENCES); diff --git a/src/audacious/plugin.h b/src/audacious/plugin.h index 90868ec..81d644e 100644 --- a/src/audacious/plugin.h +++ b/src/audacious/plugin.h @@ -1,22 +1,21 @@ /* * plugin.h - * Copyright 2005-2010 Audacious Development Team + * Copyright 2005-2012 William Pitcock, Yoshiki Yazawa, Eugene Zagidullin, and + * John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_PLUGIN_H @@ -45,8 +44,8 @@ * the API tables), increment _AUD_PLUGIN_VERSION *and* set * _AUD_PLUGIN_VERSION_MIN to the same value. */ -#define _AUD_PLUGIN_VERSION_MIN 38 /* 3.2-alpha2 */ -#define _AUD_PLUGIN_VERSION 38 +#define _AUD_PLUGIN_VERSION_MIN 40 /* 3.3-devel to 3.3-beta1 */ +#define _AUD_PLUGIN_VERSION 41 /* post 3.3-beta1 */ /* A NOTE ON THREADS * @@ -100,12 +99,18 @@ int type; /* PLUGIN_TYPE_XXX */ \ int size; /* size in bytes of the struct */ \ const char * name; \ + const char * domain; /* for gettext */ \ + const char * about_text; \ + const PluginPreferences * prefs; \ bool_t (* init) (void); \ void (* cleanup) (void); \ int (* take_message) (const char * code, const void * data, int size); \ - void (* about) (void); \ - void (* configure) (void); \ - PluginPreferences * settings; + void (* about) (void); /* use about_text instead if possible */ \ + void (* configure) (void); /* use prefs instead if possible */ \ + void * reserved1; \ + void * reserved2; \ + void * reserved3; \ + void * reserved4; struct _Plugin { @@ -122,14 +127,14 @@ struct _TransportPlugin struct _PlaylistPlugin { PLUGIN_COMMON_FIELDS - const char * const * extensions; /* array ending with NULL */ - bool_t (* load) (const char * path, VFSFile * file, - char * * title, /* pooled */ - Index * filenames, /* of (char *), pooled */ - Index * tuples); /* of (Tuple *) */ - bool_t (* save) (const char * path, VFSFile * file, const char * title, - Index * filenames, /* of (char *) */ - Index * tuples); /* of (Tuple *) */ + const char * const * extensions; /* array ending with NULL */ + bool_t (* load) (const char * path, VFSFile * file, + char * * title, /* pooled */ + Index * filenames, /* of (char *), pooled */ + Index * tuples); /* of (Tuple *) */ + bool_t (* save) (const char * path, VFSFile * file, const char * title, + Index * filenames, /* of (char *) */ + Index * tuples); /* of (Tuple *) */ }; struct _OutputPlugin @@ -169,9 +174,6 @@ struct _OutputPlugin /* Waits until all buffered data has been heard by the user. */ void (* drain) (void); - /* Returns time count (in milliseconds) of how much data has been written. */ - int (* written_time) (void); - /* Returns time count (in milliseconds) of how much data has been heard by * the user. */ int (* output_time) (void); @@ -184,11 +186,10 @@ struct _OutputPlugin * milliseconds) of data written. */ void (* flush) (int time); - /* Sets the time counter (in milliseconds) of data written without - * discarding any buffered audio data. If <time> is less than the amount of - * buffered data, following calls to output_time() will return negative - * values. */ - void (* set_written_time) (int time); + /* Whether close_audio() and open_audio() must always be called between + * songs, even if the audio format is the same. Note that this defeats + * gapless playback. */ + bool_t force_reopen; }; struct _EffectPlugin @@ -207,7 +208,7 @@ struct _EffectPlugin * passed, even a zero length. */ void (* process) (float * * data, int * samples); - /* A seek is taking place; any buffers should be discarded. */ + /* Optional. A seek is taking place; any buffers should be discarded. */ void (* flush) (void); /* Exactly like process() except that any buffers should be drained (i.e. @@ -215,10 +216,13 @@ struct _EffectPlugin * at the end of the last song in the playlist. */ void (* finish) (float * * data, int * samples); - /* Optional. For effects that change the length of the song, these - * functions allow the correct time to be displayed. */ - int (* decoder_to_output_time) (int time); - int (* output_to_decoder_time) (int time); + /* Required only for plugins that change the time domain (e.g. a time + * stretch) or use read-ahead buffering. translate_delay() must do two + * things: first, translate <delay> (which is in milliseconds) from the + * output time domain back to the input time domain; second, increase + * <delay> by the size of the read-ahead buffer. It should return the + * adjusted delay. */ + int (* adjust_delay) (int delay); /* Effects with lowest order (0 to 9) are applied first. */ int order; @@ -230,69 +234,41 @@ struct _EffectPlugin struct OutputAPI { - /* In a multi-thread plugin, only one of these functions may be called at - * once (but see pause and abort_write for exceptions to this rule). */ - - /* Prepare the output system for playback in the specified format. Returns - * nonzero on success. If the call fails, no other output functions may be + /* Prepares the output system for playback in the specified format. Returns + * TRUE on success. If the call fails, no other output functions may be * called. */ - int (* open_audio) (int format, int rate, int channels); + bool_t (* open_audio) (int format, int rate, int channels); /* Informs the output system of replay gain values for the current song so * that volume levels can be adjusted accordingly, if the user so desires. * This may be called at any time during playback should the values change. */ - void (* set_replaygain_info) (ReplayGainInfo * info); + void (* set_replaygain_info) (const ReplayGainInfo * info); - /* Pass audio data to the output system for playback. The data must be in + /* Passes audio data to the output system for playback. The data must be in * the format passed to open_audio, and the length (in bytes) must be an * integral number of frames. This function blocks until all the data has - * been written (though it may not yet be heard by the user); if the output - * system is paused; this may be indefinitely. See abort_write for a way to - * interrupt a blocked call. */ + * been written (though it may not yet be heard by the user). */ void (* write_audio) (void * data, int length); - /* End playback. Any audio data currently buffered by the output system - * will be discarded. After the call, no other output functions, except - * open_audio, may be called. */ - void (* close_audio) (void); + /* Interrupts a call to write_audio() so that it returns immediately. + * Buffered audio data is discarded. Until set_written_time() or + * open_audio() is called, further calls to write_audio() will have no + * effect and will return immediately. */ + void (* abort_write) (void); - /* Pause or unpause playback. This function may be called during a call to - * write_audio, in which write_audio will block until playback is unpaused - * (but see abort_write to prevent the call from blocking). */ + /* Pauses or unpauses playback. If playback is paused during a call to + * write_audio(), the call will block until playback is unpaused again or + * abort_write() is called. */ void (* pause) (bool_t pause); - /* Discard any audio data currently buffered by the output system, and set - * the time counter to a new value. This function is intended to be used - * for seeking. */ - void (* flush) (int time); - /* Returns the time counter. Note that this represents the amount of audio * data passed to the output system, not the amount actually heard by the - * user. This function is useful for handling a changed audio format: - * First, save the time counter using this function. Second, call - * close_audio and then open_audio with the new format (note that the call - * may fail). Finally, restore the time counter using flush. */ + * user. */ int (* written_time) (void); - /* Returns TRUE if there is data remaining in the output buffer; FALSE if - * all data written to the output system has been heard by the user. This - * function should be polled (1/50 second is a reasonable delay between - * calls) at the end of a song before calling close_audio. Once it returns - * FALSE, close_audio can be called without cutting off any of the end of - * the song. */ - bool_t (* buffer_playing) (void); - - /* Interrupt a call to write_audio so that it returns immediately. This - * works even when the call is blocked by pause. Buffered audio data is - * discarded as in flush. Until flush is called or the output system is - * reset, further calls to write_audio will have no effect and return - * immediately. This function is intended to be used in seeking or - * stopping in a multi-thread plugin. To seek, the handler function (called - * in the main thread) should first set a flag for the decoding thread and - * then call abort_write. When the decoding thread notices the flag, it - * should do the actual seek, call flush, and finally clear the flag. Once - * the flag is cleared, the handler function may return. */ - void (* abort_write) (void); + /* Sets the time counter to a new value. Does not perform a flush; the name + * is kept only for compatibility. */ + void (* flush) (int time); }; typedef const struct _InputPlayback InputPlayback; @@ -477,6 +453,7 @@ struct _IfacePlugin * is_shown() and is_focused() will return nonzero. */ void (* show) (bool_t show); bool_t (* is_shown) (void); + bool_t (* is_focused) (void); void (* show_error) (const char * markup); void (* show_filebrowser) (bool_t play_button); @@ -487,9 +464,6 @@ struct _IfacePlugin void (* install_toolbar) (void /* GtkWidget */ * button); void (* uninstall_toolbar) (void /* GtkWidget */ * button); - - /* added after 3.0-alpha1 */ - bool_t (* is_focused) (void); }; #undef PLUGIN_COMMON_FIELDS diff --git a/src/audacious/pluginenum.c b/src/audacious/pluginenum.c index 869e9ff..e06fe65 100644 --- a/src/audacious/pluginenum.c +++ b/src/audacious/pluginenum.c @@ -1,26 +1,20 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2011 Audacious development team +/* + * pluginenum.c + * Copyright 2007-2011 William Pitcock and John Lindgren * - * Based on BMP: - * Copyright (C) 2003-2004 BMP development team + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * 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 - * the Free Software Foundation; under version 3 of the License. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <assert.h> @@ -33,13 +27,8 @@ #include "config.h" -#ifndef SHARED_SUFFIX -# define SHARED_SUFFIX G_MODULE_SUFFIX -#endif - #include "debug.h" #include "plugin.h" -#include "ui_preferences.h" #include "util.h" #define AUD_API_DECLARE @@ -119,8 +108,6 @@ static void plugin2_unload (LoadedModule * loaded) case PLUGIN_TYPE_PLAYLIST: case PLUGIN_TYPE_INPUT: case PLUGIN_TYPE_EFFECT: - if (PLUGIN_HAS_FUNC (header, settings)) - plugin_preferences_cleanup (header->settings); if (PLUGIN_HAS_FUNC (header, cleanup)) header->cleanup (); break; @@ -160,9 +147,9 @@ void plugin_load (const char * filename) g_module_close(module); } -static bool_t scan_plugin_func(const char * path, const char * basename, gpointer data) +static bool_t scan_plugin_func(const char * path, const char * basename, void * data) { - if (!str_has_suffix_nocase(basename, SHARED_SUFFIX)) + if (!str_has_suffix_nocase(basename, PLUGIN_SUFFIX)) return FALSE; if (!g_file_test(path, G_FILE_TEST_IS_REGULAR)) diff --git a/src/audacious/plugins-api.h b/src/audacious/plugins-api.h index b39566e..6a1d4de 100644 --- a/src/audacious/plugins-api.h +++ b/src/audacious/plugins-api.h @@ -2,21 +2,19 @@ * plugins-api.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /* Do not include this file directly; use misc.h instead. */ @@ -50,6 +48,8 @@ AUD_VFUNC3 (plugin_for_enabled, int, type, PluginForEachFunc, func, AUD_FUNC1 (const char *, plugin_get_name, PluginHandle *, plugin) AUD_FUNC1 (bool_t, plugin_has_about, PluginHandle *, plugin) AUD_FUNC1 (bool_t, plugin_has_configure, PluginHandle *, plugin) +AUD_VFUNC1 (plugin_do_about, PluginHandle *, plugin) +AUD_VFUNC1 (plugin_do_configure, PluginHandle *, plugin) AUD_VFUNC3 (plugin_add_watch, PluginHandle *, plugin, PluginForEachFunc, func, void *, data) diff --git a/src/audacious/plugins.h b/src/audacious/plugins.h index af821dc..3456915 100644 --- a/src/audacious/plugins.h +++ b/src/audacious/plugins.h @@ -2,21 +2,19 @@ * plugins.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_PLUGINS_H @@ -43,6 +41,11 @@ enum { INPUT_KEY_MIME, INPUT_KEYS}; +typedef struct { + void * about_window; + void * config_window; +} PluginMiscData; + /* plugin-init.c */ void start_plugins_one (void); void start_plugins_two (void); @@ -57,7 +60,9 @@ void plugin_registry_save (void); void plugin_register (const char * path); void plugin_register_loaded (const char * path, Plugin * header); +const void * plugin_get_header_no_load (PluginHandle * plugin); void plugin_set_enabled (PluginHandle * plugin, bool_t enabled); +PluginMiscData * plugin_get_misc_data (PluginHandle * plugin); PluginHandle * transport_plugin_for_scheme (const char * scheme); PluginHandle * playlist_plugin_for_extension (const char * extension); diff --git a/src/audacious/preferences.h b/src/audacious/preferences.h index eb44893..bff4539 100644 --- a/src/audacious/preferences.h +++ b/src/audacious/preferences.h @@ -1,25 +1,27 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2008 Audacious development team. +/* + * preferences.h + * Copyright 2007-2011 Tomasz Moń, William Pitcock, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_PREFERENCES_H #define AUDACIOUS_PREFERENCES_H +#include <audacious/types.h> + typedef enum { WIDGET_NONE, WIDGET_CHK_BTN, @@ -45,27 +47,31 @@ typedef enum { } ValueType; typedef struct { - gpointer value; - const char *label; + void * value; + const char * label; } ComboBoxElements; struct _NotebookTab; struct _PreferencesWidget { - WidgetType type; /* widget type */ - char *label; /* widget title (for SPIN_BTN it's text left to widget) */ - gpointer cfg; /* connected config value */ - void (*callback) (void); /* this func will be called after value change, can be NULL */ - char *tooltip; /* widget tooltip, can be NULL */ + WidgetType type; /* widget type */ + const char * label; /* widget title (for SPIN_BTN it's text left to widget) */ + void * cfg; /* connected config value */ + void (* callback) (void); /* this func will be called after value change, can be NULL */ + const char * tooltip; /* widget tooltip, can be NULL */ bool_t child; - ValueType cfg_type; /* connected value type */ - const char * csect; /* config file section */ - const char * cname; /* config file key name */ + ValueType cfg_type; /* connected value type */ + const char * csect; /* config file section */ + const char * cname; /* config file key name */ union { struct { + int value; + } radio_btn; + + struct { double min, max, step; - char *right_label; /* text right to widget */ + const char * right_label; /* text right to widget */ } spin_btn; struct { @@ -74,12 +80,12 @@ struct _PreferencesWidget { } table; struct { - char *stock_id; + const char * stock_id; bool_t single_line; /* FALSE to enable line wrap */ } label; struct { - char *title; + const char * title; } font_btn; struct { @@ -87,13 +93,12 @@ struct _PreferencesWidget { } entry; struct { - ComboBoxElements *elements; + const ComboBoxElements * elements; int n_elements; - bool_t enabled; } combo; struct { - struct _PreferencesWidget *elem; + const struct _PreferencesWidget * elem; int n_elem; bool_t horizontal; /* FALSE gives vertical, TRUE gives horizontal aligment of child widgets */ @@ -101,7 +106,7 @@ struct _PreferencesWidget { } box; struct { - struct _NotebookTab *tabs; + const struct _NotebookTab * tabs; int n_tabs; } notebook; @@ -116,31 +121,18 @@ struct _PreferencesWidget { }; typedef struct _NotebookTab { - char *name; - PreferencesWidget *settings; - int n_settings; + const char * name; + const PreferencesWidget * widgets; + int n_widgets; } NotebookTab; -typedef enum { - PREFERENCES_WINDOW, /* displayed in seperate window */ -} PreferencesType; - struct _PluginPreferences { - const char * domain; - const char * title; - const char * imgurl; - - PreferencesWidget *prefs; - int n_prefs; - - PreferencesType type; + const PreferencesWidget * widgets; + int n_widgets; void (*init)(void); void (*apply)(void); - void (*cancel)(void); void (*cleanup)(void); - - gpointer data; /* for internal interface use only */ }; #endif /* AUDACIOUS_PREFERENCES_H */ diff --git a/src/audacious/probe-buffer.c b/src/audacious/probe-buffer.c index 3c0fe43..96c4f13 100644 --- a/src/audacious/probe-buffer.c +++ b/src/audacious/probe-buffer.c @@ -2,21 +2,19 @@ * probe-buffer.c * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/audacious/probe-buffer.h b/src/audacious/probe-buffer.h index 9c4405f..d1abf96 100644 --- a/src/audacious/probe-buffer.h +++ b/src/audacious/probe-buffer.h @@ -2,21 +2,19 @@ * probe-buffer.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_PROBE_BUFFER_H diff --git a/src/audacious/probe.c b/src/audacious/probe.c index b24abe4..02ef609 100644 --- a/src/audacious/probe.c +++ b/src/audacious/probe.c @@ -2,21 +2,19 @@ * probe.c * Copyright 2009-2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/audacious/signals.c b/src/audacious/signals.c index 7fda12c..1b6d177 100644 --- a/src/audacious/signals.c +++ b/src/audacious/signals.c @@ -2,21 +2,19 @@ * signals.c * Copyright 2009 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <signal.h> diff --git a/src/audacious/smclient.c b/src/audacious/smclient.c deleted file mode 100644 index 846efed..0000000 --- a/src/audacious/smclient.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Audacious - * Copyright (c) 2005-2007 Yoshiki Yazawa - * - * 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 - * the Free Software Foundation; under version 3 of the License. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. - */ - -#include <gdk/gdk.h> -#include <libaudcore/hook.h> - -#include "config.h" -#include "main.h" - -#ifdef USE_EGGSM -#include "eggsmclient.h" - -static void -signal_session_quit_cb(EggSMClient *client, gpointer user_data) -{ - const char * argv[2]; - - g_print("Session quit requested. Saving state and shutting down.\n"); - - argv[0] = "audacious"; - argv[1] = g_strdup_printf ("--display=%s", gdk_display_get_name (gdk_display_get_default())); - egg_sm_client_set_restart_command (client, 2, argv); - - hook_call ("quit", NULL); -} - -static void -signal_session_save_cb(EggSMClient *client, GKeyFile *state_file, gpointer user_data) -{ - const char * argv[2]; - - g_print("Session save requested. Saving state.\n"); - - argv[0] = "audacious"; - argv[1] = g_strdup_printf ("--display=%s", gdk_display_get_name (gdk_display_get_default())); - egg_sm_client_set_restart_command (client, 2, argv); - - do_autosave (); -} -#endif - -void smclient_init (void) -{ -#ifdef USE_EGGSM - EggSMClient *client; - - client = egg_sm_client_get (); - if (client != NULL) - { - g_signal_connect (client, "quit", - G_CALLBACK (signal_session_quit_cb), NULL); - g_signal_connect (client, "save-state", - G_CALLBACK (signal_session_save_cb), NULL); - - } -#endif -} diff --git a/src/audacious/types.h b/src/audacious/types.h index 6e789c3..83fb7e0 100644 --- a/src/audacious/types.h +++ b/src/audacious/types.h @@ -2,21 +2,19 @@ * types.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_TYPES_H diff --git a/src/audacious/ui_albumart.c b/src/audacious/ui_albumart.c index 45dd5dd..4dbff7c 100644 --- a/src/audacious/ui_albumart.c +++ b/src/audacious/ui_albumart.c @@ -1,22 +1,20 @@ /* - * Audacious: A cross-platform multimedia player - * Copyright (c) 2007 William Pitcock, Tony Vroon, George Averill, - * Giacomo Lozito, Derek Pomery and Yoshiki Yazawa. + * ui_albumart.c + * Copyright 2006 Michael Hanselmann and Yoshiki Yazawa * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> @@ -39,9 +37,9 @@ has_front_cover_extension(const char *name) return FALSE; } - return g_strcasecmp(ext, ".jpg") == 0 || - g_strcasecmp(ext, ".jpeg") == 0 || - g_strcasecmp(ext, ".png") == 0; + return g_ascii_strcasecmp(ext, ".jpg") == 0 || + g_ascii_strcasecmp(ext, ".jpeg") == 0 || + g_ascii_strcasecmp(ext, ".png") == 0; } static bool_t @@ -58,16 +56,12 @@ cover_name_filter(const char *name, const char *filter, const bool_t ret_on_empt } splitted = g_strsplit(filter, ",", 0); + lname = g_ascii_strdown (name, -1); - lname = g_strdup(name); - g_strdown(lname); - - for (i = 0; !result && (current = splitted[i]); i++) { - char *stripped = g_strstrip(g_strdup(current)); - g_strdown(stripped); - + for (i = 0; ! result && (current = splitted[i]); i ++) + { + char * stripped = g_strstrip (g_ascii_strdown (current, -1)); result = result || strstr(lname, stripped); - g_free(stripped); } diff --git a/src/audacious/ui_plugin_menu.c b/src/audacious/ui_plugin_menu.c index a614735..66475ab 100644 --- a/src/audacious/ui_plugin_menu.c +++ b/src/audacious/ui_plugin_menu.c @@ -2,21 +2,19 @@ * ui_plugin_menu.c * Copyright 2009-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/audacious/ui_preferences.c b/src/audacious/ui_preferences.c index 5eed800..6622878 100644 --- a/src/audacious/ui_preferences.c +++ b/src/audacious/ui_preferences.c @@ -1,24 +1,24 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2011 Audacious development team. +/* + * ui_preferences.c + * Copyright 2006-2011 William Pitcock, Tomasz Moń, Michael Färber, and + * John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <string.h> -#include <stdio.h> #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> @@ -27,7 +27,6 @@ #include "config.h" #include "debug.h" -#include "gtk-compat.h" #include "i18n.h" #include "misc.h" #include "output.h" @@ -42,8 +41,6 @@ #include <libguess.h> #endif -static void sw_volume_toggled (void); - enum CategoryViewCols { CATEGORY_VIEW_COL_ICON, CATEGORY_VIEW_COL_NAME, @@ -62,29 +59,17 @@ typedef struct { } TitleFieldTag; static /* GtkWidget * */ void * prefswin = NULL; -static GtkWidget *filepopup_settings = NULL; static GtkWidget *category_treeview = NULL; static GtkWidget *category_notebook = NULL; -GtkWidget *filepopupbutton = NULL; - -/* filepopup settings widgets */ -GtkWidget *filepopup_cover_name_include; -GtkWidget *filepopup_cover_name_exclude; -GtkWidget *filepopup_recurse; -GtkWidget *filepopup_recurse_depth; -GtkWidget *filepopup_recurse_depth_box; -GtkWidget *filepopup_use_file_cover; -GtkWidget *filepopup_showprogressbar; -GtkWidget *filepopup_delay; /* prefswin widgets */ GtkWidget *titlestring_entry; -GtkWidget *filepopup_settings_button; static Category categories[] = { {"audio.png", N_("Audio")}, {"connectivity.png", N_("Network")}, {"playlist.png", N_("Playlist")}, + {"info.png", N_("Song Info")}, {"plugins.png", N_("Plugins")}, }; @@ -126,7 +111,7 @@ static ComboBoxElements bitdepth_elements[] = { { GINT_TO_POINTER(16), "16" }, { GINT_TO_POINTER(24), "24" }, { GINT_TO_POINTER(32), "32" }, - {GINT_TO_POINTER (0), "Floating point"}, + {GINT_TO_POINTER (0), N_("Floating point")}, }; typedef struct { @@ -139,6 +124,7 @@ typedef struct { CategoryQueueEntry *category_queue = NULL; static void * create_output_plugin_box (void); +static void output_bit_depth_changed (void); static PreferencesWidget rg_mode_widgets[] = { {WIDGET_CHK_BTN, N_("Album mode"), .cfg_type = VALUE_BOOLEAN, .cname = "replay_gain_album"}}; @@ -147,13 +133,15 @@ static PreferencesWidget audio_page_widgets[] = { {WIDGET_LABEL, N_("<b>Output Settings</b>")}, {WIDGET_CUSTOM, .data = {.populate = create_output_plugin_box}}, {WIDGET_COMBO_BOX, N_("Bit depth:"), - .cfg_type = VALUE_INT, .cname = "output_bit_depth", - .data = {.combo = {bitdepth_elements, G_N_ELEMENTS (bitdepth_elements), TRUE}}}, + .cfg_type = VALUE_INT, .cname = "output_bit_depth", .callback = output_bit_depth_changed, + .data = {.combo = {bitdepth_elements, G_N_ELEMENTS (bitdepth_elements)}}}, {WIDGET_SPIN_BTN, N_("Buffer size:"), .cfg_type = VALUE_INT, .cname = "output_buffer_size", .data = {.spin_btn = {100, 10000, 1000, N_("ms")}}}, + {WIDGET_CHK_BTN, N_("Soft clipping"), + .cfg_type = VALUE_BOOLEAN, .cname = "soft_clipping"}, {WIDGET_CHK_BTN, N_("Use software volume control (not recommended)"), - .cfg_type = VALUE_BOOLEAN, .cname = "software_volume_control", .callback = sw_volume_toggled}, + .cfg_type = VALUE_BOOLEAN, .cname = "software_volume_control"}, {WIDGET_LABEL, N_("<b>Replay Gain</b>")}, {WIDGET_CHK_BTN, N_("Enable Replay Gain"), .cfg_type = VALUE_BOOLEAN, .cname = "enable_replay_gain"}, @@ -192,8 +180,7 @@ static PreferencesWidget chardet_elements[] = { #ifdef USE_CHARDET {WIDGET_COMBO_BOX, N_("Auto character encoding detector for:"), .cfg_type = VALUE_STRING, .cname = "chardet_detector", .child = TRUE, - .data = {.combo = {chardet_detector_presets, - G_N_ELEMENTS (chardet_detector_presets), TRUE}}}, + .data = {.combo = {chardet_detector_presets, G_N_ELEMENTS (chardet_detector_presets)}}}, #endif {WIDGET_ENTRY, N_("Fallback character encodings:"), .cfg_type = VALUE_STRING, .cname = "chardet_fallback", .child = TRUE}}; @@ -216,6 +203,28 @@ static PreferencesWidget playlist_page_widgets[] = { G_N_ELEMENTS (chardet_elements)}}} }; +static PreferencesWidget song_info_page_widgets[] = { + {WIDGET_LABEL, N_("<b>Album Art</b>")}, + {WIDGET_LABEL, N_("Search for images matching these words (comma-separated):")}, + {WIDGET_ENTRY, .cfg_type = VALUE_STRING, .cname = "cover_name_include"}, + {WIDGET_LABEL, N_("Exclude images matching these words (comma-separated):")}, + {WIDGET_ENTRY, .cfg_type = VALUE_STRING, .cname = "cover_name_exclude"}, + {WIDGET_CHK_BTN, N_("Search for images matching song file name"), + .cfg_type = VALUE_BOOLEAN, .cname = "use_file_cover"}, + {WIDGET_CHK_BTN, N_("Search recursively"), + .cfg_type = VALUE_BOOLEAN, .cname = "recurse_for_cover"}, + {WIDGET_SPIN_BTN, N_("Search depth:"), .child = TRUE, + .cfg_type = VALUE_INT, .cname = "recurse_for_cover_depth", + .data = {.spin_btn = {0, 100, 1}}}, + {WIDGET_LABEL, N_("<b>Popup Information</b>")}, + {WIDGET_CHK_BTN, N_("Show popup information"), + .cfg_type = VALUE_BOOLEAN, .cname = "show_filepopup_for_tuple"}, + {WIDGET_SPIN_BTN, N_("Popup delay (tenths of a second):"), .child = TRUE, + .cfg_type = VALUE_INT, .cname = "filepopup_delay", + .data = {.spin_btn = {0, 100, 1}}}, + {WIDGET_CHK_BTN, N_("Show time scale for current song"), .child = TRUE, + .cfg_type = VALUE_BOOLEAN, .cname = "filepopup_showprogressbar"}}; + #define TITLESTRING_NPRESETS 6 static const char * const titlestring_presets[TITLESTRING_NPRESETS] = { @@ -261,7 +270,7 @@ editable_insert_text(GtkEditable * editable, static void titlestring_tag_menu_callback(GtkMenuItem * menuitem, - gpointer data) + void * data) { const char *separator = " - "; int item = GPOINTER_TO_INT(data); @@ -281,7 +290,7 @@ titlestring_tag_menu_callback(GtkMenuItem * menuitem, static void on_titlestring_help_button_clicked(GtkButton * button, - gpointer data) + void * data) { GtkMenu * menu = data; gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME); @@ -315,7 +324,7 @@ static void on_titlestring_cbox_changed (GtkComboBox * cbox, GtkEntry * entry) gtk_entry_set_text (entry, titlestring_presets[preset]); } -static void widget_set_bool (PreferencesWidget * widget, bool_t value) +static void widget_set_bool (const PreferencesWidget * widget, bool_t value) { g_return_if_fail (widget->cfg_type == VALUE_BOOLEAN); @@ -328,7 +337,7 @@ static void widget_set_bool (PreferencesWidget * widget, bool_t value) widget->callback (); } -static bool_t widget_get_bool (PreferencesWidget * widget) +static bool_t widget_get_bool (const PreferencesWidget * widget) { g_return_val_if_fail (widget->cfg_type == VALUE_BOOLEAN, FALSE); @@ -340,7 +349,7 @@ static bool_t widget_get_bool (PreferencesWidget * widget) return FALSE; } -static void widget_set_int (PreferencesWidget * widget, int value) +static void widget_set_int (const PreferencesWidget * widget, int value) { g_return_if_fail (widget->cfg_type == VALUE_INT); @@ -353,7 +362,7 @@ static void widget_set_int (PreferencesWidget * widget, int value) widget->callback (); } -static int widget_get_int (PreferencesWidget * widget) +static int widget_get_int (const PreferencesWidget * widget) { g_return_val_if_fail (widget->cfg_type == VALUE_INT, 0); @@ -365,7 +374,7 @@ static int widget_get_int (PreferencesWidget * widget) return 0; } -static void widget_set_double (PreferencesWidget * widget, double value) +static void widget_set_double (const PreferencesWidget * widget, double value) { g_return_if_fail (widget->cfg_type == VALUE_FLOAT); @@ -378,7 +387,7 @@ static void widget_set_double (PreferencesWidget * widget, double value) widget->callback (); } -static double widget_get_double (PreferencesWidget * widget) +static double widget_get_double (const PreferencesWidget * widget) { g_return_val_if_fail (widget->cfg_type == VALUE_FLOAT, 0); @@ -390,7 +399,7 @@ static double widget_get_double (PreferencesWidget * widget) return 0; } -static void widget_set_string (PreferencesWidget * widget, const char * value) +static void widget_set_string (const PreferencesWidget * widget, const char * value) { g_return_if_fail (widget->cfg_type == VALUE_STRING); @@ -406,7 +415,7 @@ static void widget_set_string (PreferencesWidget * widget, const char * value) widget->callback (); } -static char * widget_get_string (PreferencesWidget * widget) +static char * widget_get_string (const PreferencesWidget * widget) { g_return_val_if_fail (widget->cfg_type == VALUE_STRING, NULL); @@ -418,125 +427,17 @@ static char * widget_get_string (PreferencesWidget * widget) return NULL; } -static void on_font_btn_font_set (GtkFontButton * button, PreferencesWidget * widget) +static void on_font_btn_font_set (GtkFontButton * button, const PreferencesWidget * widget) { widget_set_string (widget, gtk_font_button_get_font_name (button)); } -static void -plugin_preferences_ok(GtkWidget *widget, PluginPreferences *settings) -{ - if (settings->apply) - settings->apply(); - - gtk_widget_destroy(GTK_WIDGET(settings->data)); -} - -static void -plugin_preferences_apply(GtkWidget *widget, PluginPreferences *settings) -{ - if (settings->apply) - settings->apply(); -} - -static void -plugin_preferences_cancel(GtkWidget *widget, PluginPreferences *settings) -{ - if (settings->cancel) - settings->cancel(); - - gtk_widget_destroy(GTK_WIDGET(settings->data)); -} - -static void plugin_preferences_destroy(GtkWidget *widget, PluginPreferences *settings) -{ - gtk_widget_destroy(widget); - - if (settings->cleanup) - settings->cleanup(); - - settings->data = NULL; -} - -void plugin_preferences_show (PluginPreferences * settings) -{ - GtkWidget *window; - GtkWidget *vbox, *bbox, *ok, *apply, *cancel; - - if (settings->data != NULL) { - gtk_widget_show(GTK_WIDGET(settings->data)); - return; - } - - if (settings->init) - settings->init(); - - const char * d = settings->domain; - if (! d) - { - printf ("WARNING: PluginPreferences window with title \"%s\" did not " - "declare its gettext domain. Text may not be translated correctly.\n", - settings->title); - d = "audacious-plugins"; - } - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DIALOG); - - if (settings->title) - gtk_window_set_title ((GtkWindow *) window, dgettext (d, settings->title)); - - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - g_signal_connect(G_OBJECT(window), "destroy", - G_CALLBACK(plugin_preferences_destroy), settings); - - vbox = gtk_vbox_new(FALSE, 10); - create_widgets_with_domain ((GtkBox *) vbox, settings->prefs, - settings->n_prefs, d); - gtk_container_add(GTK_CONTAINER(window), vbox); - - bbox = gtk_hbutton_box_new(); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox), 5); - gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); - - ok = gtk_button_new_from_stock(GTK_STOCK_OK); - g_signal_connect(G_OBJECT(ok), "clicked", - G_CALLBACK(plugin_preferences_ok), settings); - gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0); - gtk_widget_set_can_default (ok, TRUE); - gtk_widget_grab_default(ok); - - apply = gtk_button_new_from_stock(GTK_STOCK_APPLY); - g_signal_connect(G_OBJECT(apply), "clicked", - G_CALLBACK(plugin_preferences_apply), settings); - gtk_box_pack_start(GTK_BOX(bbox), apply, TRUE, TRUE, 0); - - cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - g_signal_connect(G_OBJECT(cancel), "clicked", - G_CALLBACK(plugin_preferences_cancel), settings); - gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0); - - gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(prefswin)); - gtk_widget_show_all(window); - settings->data = (gpointer)window; -} - -void plugin_preferences_cleanup (PluginPreferences * p) -{ - if (p->data != NULL) - { - gtk_widget_destroy (p->data); - p->data = NULL; - } -} - -static void on_spin_btn_changed_int (GtkSpinButton * button, PreferencesWidget * widget) +static void on_spin_btn_changed_int (GtkSpinButton * button, const PreferencesWidget * widget) { widget_set_int (widget, gtk_spin_button_get_value_as_int (button)); } -static void on_spin_btn_changed_float (GtkSpinButton * button, PreferencesWidget * widget) +static void on_spin_btn_changed_float (GtkSpinButton * button, const PreferencesWidget * widget) { widget_set_double (widget, gtk_spin_button_get_value (button)); } @@ -606,67 +507,24 @@ static void fill_category_list (GtkTreeView * treeview, GtkNotebook * notebook) } } -static void on_show_filepopup_toggled (GtkToggleButton * button) +static void on_radio_button_toggled (GtkWidget * button, const PreferencesWidget * widget) { - bool_t active = gtk_toggle_button_get_active (button); - set_bool (NULL, "show_filepopup_for_tuple", active); - gtk_widget_set_sensitive (filepopup_settings_button, active); + if (gtk_toggle_button_get_active ((GtkToggleButton *) button)) + widget_set_int (widget, widget->data.radio_btn.value); } -static void on_filepopup_settings_clicked (void) +static void init_radio_button (GtkWidget * button, const PreferencesWidget * widget) { - char * string = get_string (NULL, "cover_name_include"); - gtk_entry_set_text ((GtkEntry *) filepopup_cover_name_include, string); - g_free (string); - - string = get_string (NULL, "cover_name_exclude"); - gtk_entry_set_text ((GtkEntry *) filepopup_cover_name_exclude, string); - g_free (string); - - gtk_toggle_button_set_active ((GtkToggleButton *) filepopup_recurse, - get_bool (NULL, "recurse_for_cover")); - gtk_spin_button_set_value ((GtkSpinButton *) filepopup_recurse_depth, - get_int (NULL, "recurse_for_cover_depth")); - gtk_toggle_button_set_active ((GtkToggleButton *) filepopup_use_file_cover, - get_bool (NULL, "use_file_cover")); - - gtk_toggle_button_set_active ((GtkToggleButton *) filepopup_showprogressbar, - get_bool (NULL, "filepopup_showprogressbar")); - gtk_spin_button_set_value ((GtkSpinButton *) filepopup_delay, - get_int (NULL, "filepopup_delay")); - - gtk_widget_show (filepopup_settings); -} + if (widget->cfg_type != VALUE_INT) + return; -static void on_filepopup_ok_clicked (void) -{ - set_string (NULL, "cover_name_include", - gtk_entry_get_text ((GtkEntry *) filepopup_cover_name_include)); - set_string (NULL, "cover_name_exclude", - gtk_entry_get_text ((GtkEntry *) filepopup_cover_name_exclude)); - - set_bool (NULL, "recurse_for_cover", - gtk_toggle_button_get_active ((GtkToggleButton *) filepopup_recurse)); - set_int (NULL, "recurse_for_cover_depth", - gtk_spin_button_get_value_as_int ((GtkSpinButton *) filepopup_recurse_depth)); - set_bool (NULL, "use_file_cover", - gtk_toggle_button_get_active ((GtkToggleButton *) filepopup_use_file_cover)); - - set_bool (NULL, "filepopup_showprogressbar", - gtk_toggle_button_get_active ((GtkToggleButton *) filepopup_showprogressbar)); - set_int (NULL, "filepopup_delay", - gtk_spin_button_get_value_as_int ((GtkSpinButton *) filepopup_delay)); - - gtk_widget_hide (filepopup_settings); -} + if (widget_get_int (widget) == widget->data.radio_btn.value) + gtk_toggle_button_set_active ((GtkToggleButton *) button, TRUE); -static void -on_filepopup_cancel_clicked(GtkButton *button, gpointer data) -{ - gtk_widget_hide(filepopup_settings); + g_signal_connect (button, "toggled", (GCallback) on_radio_button_toggled, (void *) widget); } -static void on_toggle_button_toggled (GtkToggleButton * button, PreferencesWidget * widget) +static void on_toggle_button_toggled (GtkToggleButton * button, const PreferencesWidget * widget) { bool_t active = gtk_toggle_button_get_active (button); widget_set_bool (widget, active); @@ -676,245 +534,78 @@ static void on_toggle_button_toggled (GtkToggleButton * button, PreferencesWidge gtk_widget_set_sensitive (child, active); } -static void init_toggle_button (GtkWidget * button, PreferencesWidget * widget) +static void init_toggle_button (GtkWidget * button, const PreferencesWidget * widget) { if (widget->cfg_type != VALUE_BOOLEAN) return; gtk_toggle_button_set_active ((GtkToggleButton *) button, widget_get_bool (widget)); - g_signal_connect (button, "toggled", (GCallback) on_toggle_button_toggled, widget); + g_signal_connect (button, "toggled", (GCallback) on_toggle_button_toggled, (void *) widget); } -static void on_entry_changed (GtkEntry * entry, PreferencesWidget * widget) +static void on_entry_changed (GtkEntry * entry, const PreferencesWidget * widget) { widget_set_string (widget, gtk_entry_get_text (entry)); } -static void on_cbox_changed_int (GtkComboBox * combobox, PreferencesWidget * widget) +static void on_cbox_changed_int (GtkComboBox * combobox, const PreferencesWidget * widget) { int position = gtk_combo_box_get_active (combobox); widget_set_int (widget, GPOINTER_TO_INT (widget->data.combo.elements[position].value)); } -static void on_cbox_changed_string (GtkComboBox * combobox, PreferencesWidget * widget) +static void on_cbox_changed_string (GtkComboBox * combobox, const PreferencesWidget * widget) { int position = gtk_combo_box_get_active (combobox); widget_set_string (widget, widget->data.combo.elements[position].value); } -static void fill_cbox (GtkWidget * combobox, PreferencesWidget * widget) +static void fill_cbox (GtkWidget * combobox, const PreferencesWidget * widget, const char * domain) { - unsigned int i=0,index=0; - - for (i = 0; i < widget->data.combo.n_elements; i ++) + for (int i = 0; i < widget->data.combo.n_elements; i ++) gtk_combo_box_text_append_text ((GtkComboBoxText *) combobox, - _(widget->data.combo.elements[i].label)); - - if (widget->data.combo.enabled) { - switch (widget->cfg_type) { - case VALUE_INT: - g_signal_connect(combobox, "changed", - G_CALLBACK(on_cbox_changed_int), widget); - - int ivalue = widget_get_int (widget); - - for(i=0; i<widget->data.combo.n_elements; i++) { - if (GPOINTER_TO_INT (widget->data.combo.elements[i].value) == ivalue) - { - index = i; - break; - } - } - break; - case VALUE_STRING: - g_signal_connect(combobox, "changed", - G_CALLBACK(on_cbox_changed_string), widget); - - char * value = widget_get_string (widget); - - for(i=0; i<widget->data.combo.n_elements; i++) { - if (value && ! strcmp ((char *) widget->data.combo.elements[i].value, value)) - { - index = i; - break; - } - } + dgettext (domain, widget->data.combo.elements[i].label)); + + switch (widget->cfg_type) + { + case VALUE_INT:; + int ivalue = widget_get_int (widget); - g_free (value); + for (int i = 0; i < widget->data.combo.n_elements; i++) + { + if (GPOINTER_TO_INT (widget->data.combo.elements[i].value) == ivalue) + { + gtk_combo_box_set_active ((GtkComboBox *) combobox, i); break; - default: + } + } + + g_signal_connect (combobox, "changed", (GCallback) on_cbox_changed_int, (void *) widget); + break; + + case VALUE_STRING:; + char * value = widget_get_string (widget); + + for(int i = 0; i < widget->data.combo.n_elements; i++) + { + if (value && ! strcmp (widget->data.combo.elements[i].value, value)) + { + gtk_combo_box_set_active ((GtkComboBox *) combobox, i); break; + } } - gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), index); - } else { - gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), -1); - gtk_widget_set_sensitive(GTK_WIDGET(combobox), 0); - } -} -void -create_filepopup_settings(void) -{ - GtkWidget *vbox; - GtkWidget *table; - - GtkWidget *label_cover_retrieve; - GtkWidget *label_cover_search; - GtkWidget *label_exclude; - GtkWidget *label_include; - GtkWidget *label_search_depth; - GtkWidget *label_misc; - GtkWidget *label_delay; - - GtkAdjustment *recurse_for_cover_depth_adj; - GtkAdjustment *delay_adj; - GtkWidget *alignment; - - GtkWidget *hbox; - GtkWidget *hbuttonbox; - GtkWidget *btn_cancel; - GtkWidget *btn_ok; - - filepopup_settings = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_container_set_border_width(GTK_CONTAINER(filepopup_settings), 12); - gtk_window_set_title(GTK_WINDOW(filepopup_settings), _("Popup Information Settings")); - gtk_window_set_position(GTK_WINDOW(filepopup_settings), GTK_WIN_POS_CENTER_ON_PARENT); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(filepopup_settings), TRUE); - gtk_window_set_type_hint(GTK_WINDOW(filepopup_settings), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_transient_for(GTK_WINDOW(filepopup_settings), GTK_WINDOW(prefswin)); - - vbox = gtk_vbox_new(FALSE, 12); - gtk_container_add(GTK_CONTAINER(filepopup_settings), vbox); - - label_cover_retrieve = gtk_label_new(_("<b>Cover image retrieve</b>")); - gtk_box_pack_start(GTK_BOX(vbox), label_cover_retrieve, FALSE, FALSE, 0); - gtk_label_set_use_markup(GTK_LABEL(label_cover_retrieve), TRUE); - gtk_misc_set_alignment(GTK_MISC(label_cover_retrieve), 0, 0.5); - - label_cover_search = gtk_label_new(_("While searching for the album's cover, Audacious looks for certain words in the filename. You can specify those words in the lists below, separated using commas.")); - gtk_box_pack_start(GTK_BOX(vbox), label_cover_search, FALSE, FALSE, 0); - gtk_label_set_line_wrap(GTK_LABEL(label_cover_search), TRUE); - gtk_misc_set_alignment(GTK_MISC(label_cover_search), 0, 0); - gtk_misc_set_padding(GTK_MISC(label_cover_search), 12, 0); - - table = gtk_table_new(2, 2, FALSE); - gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); - gtk_table_set_row_spacings(GTK_TABLE(table), 4); - gtk_table_set_col_spacings(GTK_TABLE(table), 4); - - filepopup_cover_name_include = gtk_entry_new(); - gtk_table_attach(GTK_TABLE(table), filepopup_cover_name_include, 1, 2, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_entry_set_activates_default(GTK_ENTRY(filepopup_cover_name_include), TRUE); - - label_exclude = gtk_label_new(_("Exclude:")); - gtk_table_attach(GTK_TABLE(table), label_exclude, 0, 1, 1, 2, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label_exclude), 0, 0.5); - gtk_misc_set_padding(GTK_MISC(label_exclude), 12, 0); - - label_include = gtk_label_new(_("Include:")); - gtk_table_attach(GTK_TABLE(table), label_include, 0, 1, 0, 1, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label_include), 0, 0.5); - gtk_misc_set_padding(GTK_MISC(label_include), 12, 0); - - filepopup_cover_name_exclude = gtk_entry_new(); - gtk_table_attach(GTK_TABLE(table), filepopup_cover_name_exclude, 1, 2, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_entry_set_activates_default(GTK_ENTRY(filepopup_cover_name_exclude), TRUE); - - alignment = gtk_alignment_new(0.5, 0.5, 1, 1); - gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0); - - filepopup_recurse = gtk_check_button_new_with_mnemonic(_("Recursively search for cover")); - gtk_container_add(GTK_CONTAINER(alignment), filepopup_recurse); - - alignment = gtk_alignment_new(0.5, 0.5, 1, 1); - gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 45, 0); - - filepopup_recurse_depth_box = gtk_hbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(alignment), filepopup_recurse_depth_box); - - label_search_depth = gtk_label_new(_("Search depth: ")); - gtk_box_pack_start(GTK_BOX(filepopup_recurse_depth_box), label_search_depth, TRUE, TRUE, 0); - gtk_misc_set_padding(GTK_MISC(label_search_depth), 4, 0); - - recurse_for_cover_depth_adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, - 100, 1, 10, 0); - filepopup_recurse_depth = gtk_spin_button_new(GTK_ADJUSTMENT(recurse_for_cover_depth_adj), 1, 0); - gtk_box_pack_start(GTK_BOX(filepopup_recurse_depth_box), filepopup_recurse_depth, TRUE, TRUE, 0); - gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(filepopup_recurse_depth), TRUE); - - alignment = gtk_alignment_new(0.5, 0.5, 1, 1); - gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0); - - filepopup_use_file_cover = gtk_check_button_new_with_mnemonic(_("Use per-file cover")); - gtk_container_add(GTK_CONTAINER(alignment), filepopup_use_file_cover); - - label_misc = gtk_label_new(_("<b>Miscellaneous</b>")); - gtk_box_pack_start(GTK_BOX(vbox), label_misc, FALSE, FALSE, 0); - gtk_label_set_use_markup(GTK_LABEL(label_misc), TRUE); - gtk_misc_set_alignment(GTK_MISC(label_misc), 0, 0.5); - - alignment = gtk_alignment_new(0.5, 0.5, 1, 1); - gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0); - - filepopup_showprogressbar = gtk_check_button_new_with_mnemonic(_("Show Progress bar for the current track")); - gtk_container_add(GTK_CONTAINER(alignment), filepopup_showprogressbar); - - alignment = gtk_alignment_new(0, 0.5, 1, 1); - gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0); - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0); - - hbox = gtk_hbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(alignment), hbox); - - label_delay = gtk_label_new(_("Delay until filepopup comes up: ")); - gtk_box_pack_start(GTK_BOX(hbox), label_delay, TRUE, TRUE, 0); - gtk_misc_set_alignment(GTK_MISC(label_delay), 0, 0.5); - gtk_misc_set_padding(GTK_MISC(label_delay), 12, 0); - - delay_adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 100, 1, 10, 0); - filepopup_delay = gtk_spin_button_new(GTK_ADJUSTMENT(delay_adj), 1, 0); - gtk_box_pack_start(GTK_BOX(hbox), filepopup_delay, TRUE, TRUE, 0); - gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(filepopup_delay), TRUE); - - hbuttonbox = gtk_hbutton_box_new(); - gtk_box_pack_start(GTK_BOX(vbox), hbuttonbox, FALSE, FALSE, 0); - gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(hbuttonbox), 6); - - btn_cancel = gtk_button_new_from_stock("gtk-cancel"); - gtk_container_add(GTK_CONTAINER(hbuttonbox), btn_cancel); - - btn_ok = gtk_button_new_from_stock("gtk-ok"); - gtk_container_add(GTK_CONTAINER(hbuttonbox), btn_ok); - gtk_widget_set_can_default(btn_ok, TRUE); - - g_signal_connect(G_OBJECT(filepopup_settings), "delete_event", - G_CALLBACK(gtk_widget_hide_on_delete), - NULL); - g_signal_connect(G_OBJECT(btn_cancel), "clicked", - G_CALLBACK(on_filepopup_cancel_clicked), - NULL); - g_signal_connect(G_OBJECT(btn_ok), "clicked", - G_CALLBACK(on_filepopup_ok_clicked), - NULL); + g_free (value); - gtk_widget_grab_default(btn_ok); - gtk_widget_show_all(vbox); + g_signal_connect (combobox, "changed", (GCallback) on_cbox_changed_string, (void *) widget); + break; + + default: + break; + } } -static void create_spin_button (PreferencesWidget * widget, GtkWidget * * +static void create_spin_button (const PreferencesWidget * widget, GtkWidget * * label_pre, GtkWidget * * spin_btn, GtkWidget * * label_past, const char * domain) { @@ -940,24 +631,26 @@ static void create_spin_button (PreferencesWidget * widget, GtkWidget * * { case VALUE_INT: gtk_spin_button_set_value ((GtkSpinButton *) * spin_btn, widget_get_int (widget)); - g_signal_connect (* spin_btn, "value_changed", (GCallback) on_spin_btn_changed_int, widget); + g_signal_connect (* spin_btn, "value_changed", (GCallback) + on_spin_btn_changed_int, (void *) widget); break; case VALUE_FLOAT: gtk_spin_button_set_value ((GtkSpinButton *) * spin_btn, widget_get_double (widget)); g_signal_connect (* spin_btn, "value_changed", (GCallback) - on_spin_btn_changed_float, widget); + on_spin_btn_changed_float, (void *) widget); break; default: break; } } -void create_font_btn (PreferencesWidget * widget, GtkWidget * * label, +void create_font_btn (const PreferencesWidget * widget, GtkWidget * * label, GtkWidget * * font_btn, const char * domain) { *font_btn = gtk_font_button_new(); gtk_font_button_set_use_font(GTK_FONT_BUTTON(*font_btn), TRUE); gtk_font_button_set_use_size(GTK_FONT_BUTTON(*font_btn), TRUE); + gtk_widget_set_hexpand(*font_btn, TRUE); if (widget->label) { * label = gtk_label_new_with_mnemonic (dgettext (domain, widget->label)); gtk_label_set_use_markup(GTK_LABEL(*label), TRUE); @@ -977,14 +670,15 @@ void create_font_btn (PreferencesWidget * widget, GtkWidget * * label, g_free (name); } - g_signal_connect (* font_btn, "font_set", (GCallback) on_font_btn_font_set, widget); + g_signal_connect (* font_btn, "font_set", (GCallback) on_font_btn_font_set, (void *) widget); } -static void create_entry (PreferencesWidget * widget, GtkWidget * * label, +static void create_entry (const PreferencesWidget * widget, GtkWidget * * label, GtkWidget * * entry, const char * domain) { *entry = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(*entry), !widget->data.entry.password); + gtk_widget_set_hexpand(*entry, TRUE); if (widget->label) * label = gtk_label_new (dgettext (domain, widget->label)); @@ -1001,11 +695,11 @@ static void create_entry (PreferencesWidget * widget, GtkWidget * * label, g_free (value); } - g_signal_connect (* entry, "changed", (GCallback) on_entry_changed, widget); + g_signal_connect (* entry, "changed", (GCallback) on_entry_changed, (void *) widget); } } -static void create_label (PreferencesWidget * widget, GtkWidget * * label, +static void create_label (const PreferencesWidget * widget, GtkWidget * * label, GtkWidget * * icon, const char * domain) { if (widget->data.label.stock_id) @@ -1020,7 +714,7 @@ static void create_label (PreferencesWidget * widget, GtkWidget * * label, gtk_misc_set_alignment(GTK_MISC(*label), 0, 0.5); } -static void create_cbox (PreferencesWidget * widget, GtkWidget * * label, +static void create_cbox (const PreferencesWidget * widget, GtkWidget * * label, GtkWidget * * combobox, const char * domain) { * combobox = gtk_combo_box_text_new (); @@ -1029,15 +723,14 @@ static void create_cbox (PreferencesWidget * widget, GtkWidget * * label, * label = gtk_label_new (dgettext (domain, widget->label)); } - fill_cbox (* combobox, widget); + fill_cbox (* combobox, widget, domain); } -static void fill_table (GtkWidget * table, PreferencesWidget * elements, int +static void fill_grid (GtkWidget * grid, const PreferencesWidget * elements, int amt, const char * domain) { int x; GtkWidget *widget_left, *widget_middle, *widget_right; - GtkAttachOptions middle_policy = (GtkAttachOptions) (0); for (x = 0; x < amt; ++x) { widget_left = widget_middle = widget_right = NULL; @@ -1045,64 +738,54 @@ static void fill_table (GtkWidget * table, PreferencesWidget * elements, int case WIDGET_SPIN_BTN: create_spin_button (& elements[x], & widget_left, & widget_middle, & widget_right, domain); - middle_policy = (GtkAttachOptions) (GTK_FILL); break; case WIDGET_LABEL: create_label (& elements[x], & widget_middle, & widget_left, domain); - middle_policy = (GtkAttachOptions) (GTK_FILL); break; case WIDGET_FONT_BTN: create_font_btn (& elements[x], & widget_left, & widget_middle, domain); - middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL); break; case WIDGET_ENTRY: create_entry (& elements[x], & widget_left, & widget_middle, domain); - middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL); break; case WIDGET_COMBO_BOX: create_cbox (& elements[x], & widget_left, & widget_middle, domain); - middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL); break; default: g_warning("Unsupported widget type %d in table", elements[x].type); } if (widget_left) - gtk_table_attach(GTK_TABLE (table), widget_left, 0, 1, x, x+1, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); + gtk_grid_attach(GTK_GRID(grid), widget_left, 0, x, 1, 1); if (widget_middle) - gtk_table_attach(GTK_TABLE(table), widget_middle, 1, widget_right ? 2 : 3, x, x+1, - middle_policy, - (GtkAttachOptions) (0), 4, 0); + gtk_grid_attach(GTK_GRID(grid), widget_middle, 1, x, 1, 1); if (widget_right) - gtk_table_attach(GTK_TABLE(table), widget_right, 2, 3, x, x+1, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); + gtk_grid_attach(GTK_GRID(grid), widget_right, 2, x, 1, 1); } } -/* void create_widgets_with_domain (GtkBox * box, PreferencesWidget * widgets, - int amt, const char * domain) */ -void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int - amt, const char * domain) +/* box: a GtkBox */ +void create_widgets_with_domain (void * box, const PreferencesWidget * widgets, + int amt, const char * domain) { - int x; GtkWidget *alignment = NULL, *widget = NULL; GtkWidget *child_box = NULL; GSList *radio_btn_group = NULL; - for (x = 0; x < amt; ++x) { + for (int x = 0; x < amt; x ++) + { + GtkWidget * label = NULL; + if (widget && widgets[x].child) { if (!child_box) { - child_box = gtk_vbox_new(FALSE, 0); + child_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); g_object_set_data(G_OBJECT(widget), "child", child_box); alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_box_pack_start(box, alignment, FALSE, FALSE, 0); @@ -1128,15 +811,17 @@ void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int init_toggle_button (widget, & widgets[x]); break; case WIDGET_LABEL: - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 12, 0, 0, 0); + if (strstr (widgets[x].label, "<b>")) + gtk_alignment_set_padding ((GtkAlignment *) alignment, + (x == 0) ? 0 : 12, 0, 0, 0); - GtkWidget *label = NULL, *icon = NULL; + GtkWidget * icon = NULL; create_label (& widgets[x], & label, & icon, domain); if (icon == NULL) widget = label; else { - widget = gtk_hbox_new(FALSE, 6); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(widget), icon, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 0); } @@ -1145,10 +830,10 @@ void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int widget = gtk_radio_button_new_with_mnemonic (radio_btn_group, dgettext (domain, widgets[x].label)); radio_btn_group = gtk_radio_button_get_group ((GtkRadioButton *) widget); - init_toggle_button (widget, & widgets[x]); + init_radio_button (widget, & widgets[x]); break; case WIDGET_SPIN_BTN: - widget = gtk_hbox_new(FALSE, 6); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); GtkWidget *label_pre = NULL, *spin_btn = NULL, *label_past = NULL; create_spin_button (& widgets[x], & label_pre, & spin_btn, @@ -1170,7 +855,7 @@ void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int break; case WIDGET_FONT_BTN: - widget = gtk_hbox_new(FALSE, 6); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); GtkWidget *font_btn = NULL; create_font_btn (& widgets[x], & label, & font_btn, domain); @@ -1181,13 +866,14 @@ void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int gtk_box_pack_start(GTK_BOX(widget), font_btn, FALSE, FALSE, 0); break; case WIDGET_TABLE: - widget = gtk_table_new(widgets[x].data.table.rows, 3, FALSE); - fill_table (widget, widgets[x].data.table.elem, + widget = gtk_grid_new(); + fill_grid(widget, widgets[x].data.table.elem, widgets[x].data.table.rows, domain); - gtk_table_set_row_spacings(GTK_TABLE(widget), 6); + gtk_grid_set_column_spacing(GTK_GRID(widget), 6); + gtk_grid_set_row_spacing(GTK_GRID(widget), 6); break; case WIDGET_ENTRY: - widget = gtk_hbox_new(FALSE, 6); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); GtkWidget *entry = NULL; create_entry (& widgets[x], & label, & entry, domain); @@ -1198,7 +884,7 @@ void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int gtk_box_pack_start(GTK_BOX(widget), entry, TRUE, TRUE, 0); break; case WIDGET_COMBO_BOX: - widget = gtk_hbox_new(FALSE, 6); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); GtkWidget *combo = NULL; create_cbox (& widgets[x], & label, & combo, domain); @@ -1212,9 +898,9 @@ void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 0, 0); if (widgets[x].data.box.horizontal) { - widget = gtk_hbox_new(FALSE, 0); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); } else { - widget = gtk_vbox_new(FALSE, 0); + widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); } create_widgets_with_domain ((GtkBox *) widget, @@ -1236,10 +922,10 @@ void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int int i; for (i = 0; i<widgets[x].data.notebook.n_tabs; i++) { GtkWidget *vbox; - vbox = gtk_vbox_new(FALSE, 5); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); create_widgets_with_domain ((GtkBox *) vbox, - widgets[x].data.notebook.tabs[i].settings, - widgets[x].data.notebook.tabs[i].n_settings, domain); + widgets[x].data.notebook.tabs[i].widgets, + widgets[x].data.notebook.tabs[i].n_widgets, domain); gtk_notebook_append_page (GTK_NOTEBOOK (widget), vbox, gtk_label_new (dgettext (domain, @@ -1250,9 +936,9 @@ void create_widgets_with_domain (void * box, PreferencesWidget * widgets, int gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 6, 0, 0); if (widgets[x].data.separator.horizontal == TRUE) { - widget = gtk_hseparator_new(); + widget = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); } else { - widget = gtk_vseparator_new(); + widget = gtk_separator_new (GTK_ORIENTATION_VERTICAL); } break; default: @@ -1326,21 +1012,15 @@ create_playlist_category(void) GtkWidget *alignment55; GtkWidget *label60; GtkWidget *alignment56; - GtkWidget *table6; + GtkWidget *grid6; GtkWidget *titlestring_help_button; GtkWidget *image1; GtkWidget *label62; GtkWidget *label61; - GtkWidget *alignment85; - GtkWidget *label84; - GtkWidget *alignment86; - GtkWidget *hbox9; - GtkWidget *vbox34; - GtkWidget *image8; GtkWidget *titlestring_tag_menu = create_titlestring_tag_menu(); GtkWidget * numbers_alignment, * numbers; - vbox5 = gtk_vbox_new (FALSE, 0); + vbox5 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add ((GtkContainer *) category_notebook, vbox5); create_widgets(GTK_BOX(vbox5), playlist_page_widgets, G_N_ELEMENTS(playlist_page_widgets)); @@ -1380,15 +1060,13 @@ create_playlist_category(void) gtk_box_pack_start (GTK_BOX (vbox5), alignment56, FALSE, FALSE, 0); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment56), 0, 0, 12, 0); - table6 = gtk_table_new (2, 3, FALSE); - gtk_container_add (GTK_CONTAINER (alignment56), table6); - gtk_table_set_row_spacings (GTK_TABLE (table6), 4); - gtk_table_set_col_spacings (GTK_TABLE (table6), 12); + grid6 = gtk_grid_new (); + gtk_container_add (GTK_CONTAINER (alignment56), grid6); + gtk_grid_set_row_spacing (GTK_GRID (grid6), 4); + gtk_grid_set_column_spacing (GTK_GRID (grid6), 12); titlestring_help_button = gtk_button_new (); - gtk_table_attach (GTK_TABLE (table6), titlestring_help_button, 2, 3, 1, 2, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); + gtk_grid_attach (GTK_GRID (grid6), titlestring_help_button, 2, 1, 1, 1); gtk_widget_set_can_focus (titlestring_help_button, FALSE); gtk_widget_set_tooltip_text (titlestring_help_button, _("Show information about titlestring format")); @@ -1400,79 +1078,32 @@ create_playlist_category(void) GtkWidget * titlestring_cbox; create_titlestring_widgets (& titlestring_cbox, & titlestring_entry); - gtk_table_attach (GTK_TABLE (table6), titlestring_cbox, 1, 3, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_table_attach (GTK_TABLE (table6), titlestring_entry, 1, 2, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); + gtk_widget_set_hexpand (titlestring_cbox, TRUE); + gtk_widget_set_hexpand (titlestring_entry, TRUE); + gtk_grid_attach (GTK_GRID (grid6), titlestring_cbox, 1, 0, 1, 1); + gtk_grid_attach (GTK_GRID (grid6), titlestring_entry, 1, 1, 1, 1); label62 = gtk_label_new (_("Custom string:")); - gtk_table_attach (GTK_TABLE (table6), label62, 0, 1, 1, 2, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); + gtk_grid_attach (GTK_GRID (grid6), label62, 0, 1, 1, 1); gtk_label_set_justify (GTK_LABEL (label62), GTK_JUSTIFY_RIGHT); gtk_misc_set_alignment (GTK_MISC (label62), 1, 0.5); label61 = gtk_label_new (_("Title format:")); - gtk_table_attach (GTK_TABLE (table6), label61, 0, 1, 0, 1, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); + gtk_grid_attach (GTK_GRID (grid6), label61, 0, 0, 1, 1); gtk_label_set_justify (GTK_LABEL (label61), GTK_JUSTIFY_RIGHT); gtk_misc_set_alignment (GTK_MISC (label61), 1, 0.5); - alignment85 = gtk_alignment_new (0.5, 0.5, 1, 1); - gtk_box_pack_start (GTK_BOX (vbox5), alignment85, FALSE, FALSE, 0); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment85), 12, 12, 0, 0); - - label84 = gtk_label_new (_("<b>Popup Information</b>")); - gtk_container_add (GTK_CONTAINER (alignment85), label84); - gtk_label_set_use_markup (GTK_LABEL (label84), TRUE); - gtk_misc_set_alignment (GTK_MISC (label84), 0, 0.5); - - alignment86 = gtk_alignment_new (0.5, 0.5, 1, 1); - gtk_box_pack_start (GTK_BOX (vbox5), alignment86, FALSE, FALSE, 0); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment86), 0, 0, 12, 0); - - hbox9 = gtk_hbox_new (FALSE, 12); - gtk_container_add (GTK_CONTAINER (alignment86), hbox9); - - vbox34 = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (hbox9), vbox34, TRUE, TRUE, 0); - - filepopupbutton = gtk_check_button_new_with_mnemonic (_("Show popup information for playlist entries")); - gtk_widget_set_tooltip_text (filepopupbutton, _("Toggles popup information window for the pointed entry in the playlist. The window shows title of song, name of album, genre, year of publish, track number, track length, and artwork.")); - gtk_toggle_button_set_active ((GtkToggleButton *) filepopupbutton, - get_bool (NULL, "show_filepopup_for_tuple")); - gtk_box_pack_start ((GtkBox *) vbox34, filepopupbutton, TRUE, FALSE, 0); - - filepopup_settings_button = gtk_button_new (); - gtk_widget_set_sensitive (filepopup_settings_button, - get_bool (NULL, "show_filepopup_for_tuple")); - gtk_box_pack_start (GTK_BOX (hbox9), filepopup_settings_button, FALSE, FALSE, 0); - - gtk_widget_set_can_focus (filepopup_settings_button, FALSE); - gtk_widget_set_tooltip_text (filepopup_settings_button, _("Edit settings for popup information")); - gtk_button_set_relief (GTK_BUTTON (filepopup_settings_button), GTK_RELIEF_HALF); - - image8 = gtk_image_new_from_stock ("gtk-properties", GTK_ICON_SIZE_BUTTON); - gtk_container_add (GTK_CONTAINER (filepopup_settings_button), image8); - - - - g_signal_connect (filepopupbutton, "toggled", - G_CALLBACK(on_show_filepopup_toggled), - NULL); - g_signal_connect(G_OBJECT(filepopup_settings_button), "clicked", - G_CALLBACK(on_filepopup_settings_clicked), - NULL); - g_signal_connect(titlestring_help_button, "clicked", G_CALLBACK(on_titlestring_help_button_clicked), titlestring_tag_menu); +} - /* Create window for filepopup settings */ - create_filepopup_settings(); +static void create_song_info_category (void) +{ + GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add ((GtkContainer *) category_notebook, vbox); + create_widgets ((GtkBox *) vbox, song_info_page_widgets, + G_N_ELEMENTS (song_info_page_widgets)); } static GtkWidget * output_config_button, * output_about_button; @@ -1522,37 +1153,40 @@ static void output_combo_fill (GtkComboBox * combo) plugin_get_name (node->data)); } +static void output_bit_depth_changed (void) +{ + output_reset (OUTPUT_RESET_SOFT); +} + static void output_do_config (void) { - OutputPlugin * op = plugin_get_header (output_plugin_get_current ()); - g_return_if_fail (op != NULL); - if (op->configure != NULL) - op->configure (); + PluginHandle * plugin = output_plugin_get_current (); + g_return_if_fail (plugin != NULL); + plugin_do_configure (plugin); } static void output_do_about (void) { - OutputPlugin * op = plugin_get_header (output_plugin_get_current ()); - g_return_if_fail (op != NULL); - if (op->about != NULL) - op->about (); + PluginHandle * plugin = output_plugin_get_current (); + g_return_if_fail (plugin != NULL); + plugin_do_about (plugin); } static void * create_output_plugin_box (void) { - GtkWidget * hbox1 = gtk_hbox_new (FALSE, 6); + GtkWidget * hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) hbox1, gtk_label_new (_("Output plugin:")), FALSE, FALSE, 0); - GtkWidget * vbox = gtk_vbox_new (FALSE, 6); + GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_box_pack_start ((GtkBox *) hbox1, vbox, FALSE, FALSE, 0); - GtkWidget * hbox2 = gtk_hbox_new (FALSE, 6); + GtkWidget * hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox, hbox2, FALSE, FALSE, 0); GtkWidget * output_plugin_cbox = gtk_combo_box_text_new (); gtk_box_pack_start ((GtkBox *) hbox2, output_plugin_cbox, FALSE, FALSE, 0); - GtkWidget * hbox3 = gtk_hbox_new (FALSE, 6); + GtkWidget * hbox3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox, hbox3, FALSE, FALSE, 0); output_config_button = gtk_button_new_from_stock (GTK_STOCK_PREFERENCES); @@ -1573,7 +1207,7 @@ static void * create_output_plugin_box (void) static void create_audio_category (void) { - GtkWidget * audio_page_vbox = gtk_vbox_new (FALSE, 0); + GtkWidget * audio_page_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); create_widgets ((GtkBox *) audio_page_vbox, audio_page_widgets, G_N_ELEMENTS (audio_page_widgets)); gtk_container_add ((GtkContainer *) category_notebook, audio_page_vbox); } @@ -1584,10 +1218,10 @@ create_connectivity_category(void) GtkWidget *connectivity_page_vbox; GtkWidget *vbox29; - connectivity_page_vbox = gtk_vbox_new (FALSE, 0); + connectivity_page_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (category_notebook), connectivity_page_vbox); - vbox29 = gtk_vbox_new (FALSE, 0); + vbox29 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start (GTK_BOX (connectivity_page_vbox), vbox29, TRUE, TRUE, 0); create_widgets(GTK_BOX(vbox29), connectivity_page_widgets, G_N_ELEMENTS(connectivity_page_widgets)); @@ -1609,12 +1243,10 @@ static void create_plugin_category (void) } static bool_t -prefswin_destroy(GtkWidget *window, GdkEvent *event, gpointer data) +prefswin_destroy(GtkWidget *window, GdkEvent *event, void * data) { prefswin = NULL; category_notebook = NULL; - gtk_widget_destroy(filepopup_settings); - filepopup_settings = NULL; gtk_widget_destroy(window); return TRUE; } @@ -1645,10 +1277,10 @@ void * * create_prefs_window (void) gtk_window_set_position (GTK_WINDOW (prefswin), GTK_WIN_POS_CENTER); gtk_window_set_default_size (GTK_WINDOW (prefswin), 680, 400); - vbox = gtk_vbox_new (FALSE, 0); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (prefswin), vbox); - hbox1 = gtk_hbox_new (FALSE, 8); + hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); gtk_box_pack_start (GTK_BOX (vbox), hbox1, TRUE, TRUE, 0); scrolledwindow6 = gtk_scrolled_window_new (NULL, NULL); @@ -1672,24 +1304,25 @@ void * * create_prefs_window (void) create_audio_category(); create_connectivity_category(); create_playlist_category(); + create_song_info_category(); create_plugin_category(); - hseparator1 = gtk_hseparator_new (); + hseparator1 = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); gtk_box_pack_start (GTK_BOX (vbox), hseparator1, FALSE, FALSE, 6); - hbox4 = gtk_hbox_new (FALSE, 0); + hbox4 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox4, FALSE, FALSE, 0); audversionlabel = gtk_label_new (""); gtk_box_pack_start (GTK_BOX (hbox4), audversionlabel, FALSE, FALSE, 0); gtk_label_set_use_markup (GTK_LABEL (audversionlabel), TRUE); - prefswin_button_box = gtk_hbutton_box_new (); + prefswin_button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); gtk_box_pack_start (GTK_BOX (hbox4), prefswin_button_box, TRUE, TRUE, 0); gtk_button_box_set_layout (GTK_BUTTON_BOX (prefswin_button_box), GTK_BUTTONBOX_END); gtk_box_set_spacing (GTK_BOX (prefswin_button_box), 6); - hbox11 = gtk_hbox_new (FALSE, 2); + hbox11 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); image10 = gtk_image_new_from_stock ("gtk-refresh", GTK_ICON_SIZE_BUTTON); gtk_box_pack_start (GTK_BOX (hbox11), image10, FALSE, FALSE, 0); @@ -1698,7 +1331,7 @@ void * * create_prefs_window (void) gtk_container_add (GTK_CONTAINER (prefswin_button_box), close); gtk_widget_set_can_default(close, TRUE); gtk_widget_add_accelerator (close, "clicked", accel_group, - GDK_Escape, (GdkModifierType) 0, + GDK_KEY_Escape, (GdkModifierType) 0, GTK_ACCEL_VISIBLE); @@ -1875,18 +1508,3 @@ prefswin_page_destroy(GtkWidget *container) ret = gtk_tree_model_iter_next(model, &iter); } } - -static void sw_volume_toggled (void) -{ - int vol[2]; - - if (get_bool (NULL, "software_volume_control")) - { - vol[0] = get_int (NULL, "sw_volume_left"); - vol[1] = get_int (NULL, "sw_volume_right"); - } - else - playback_get_volume (& vol[0], & vol[1]); - - hook_call ("volume set", vol); -} diff --git a/src/audacious/ui_preferences.h b/src/audacious/ui_preferences.h index 21a01bb..408fb50 100644 --- a/src/audacious/ui_preferences.h +++ b/src/audacious/ui_preferences.h @@ -1,20 +1,20 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. +/* + * ui_preferences.h + * Copyright 2006-2010 William Pitcock, Tomasz Moń, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_UI_PREFERENCES_H @@ -36,8 +36,10 @@ int prefswin_page_new (void * container, const char * name, const char * imgurl); void prefswin_page_destroy(GtkWidget *container); -void plugin_preferences_show (PluginPreferences * p); -void plugin_preferences_cleanup (PluginPreferences * p); +/* plugin-preferences.c */ +void plugin_make_about_window (PluginHandle * plugin); +void plugin_make_config_window (PluginHandle * plugin); +void plugin_misc_cleanup (PluginHandle * plugin); /* plugin-view.c */ GtkWidget * plugin_view_new (int type); diff --git a/src/audacious/util.c b/src/audacious/util.c index 84a858f..b262fcf 100644 --- a/src/audacious/util.c +++ b/src/audacious/util.c @@ -1,26 +1,20 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2011 Audacious development team +/* + * util.c + * Copyright 2009-2012 John Lindgren and Michał Lipski * - * Based on BMP: - * Copyright (C) 2003-2004 BMP development team. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * 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 - * the Free Software Foundation; under version 3 of the License. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <dirent.h> @@ -194,6 +188,25 @@ char * get_path_to_self (void) size += size; buf = g_realloc (buf, size); } +#elif defined __APPLE__ + unsigned int size = 256; + char * buf = g_malloc (size); + + while (1) + { + int res; + + if (! (res = _NSGetExecutablePath (buf, &size))) + return buf; + + if (res == -1) + buf = g_realloc (buf, size); + else + { + g_free (buf); + return NULL; + } + } #else return NULL; #endif diff --git a/src/audacious/util.h b/src/audacious/util.h index a42a453..f1e0978 100644 --- a/src/audacious/util.h +++ b/src/audacious/util.h @@ -1,26 +1,20 @@ -/* Audacious - Cross-platform multimedia player - * Copyright (C) 2005-2011 Audacious development team +/* + * util.h + * Copyright 2009-2011 John Lindgren * - * Based on BMP: - * Copyright (C) 2003-2004 BMP development team + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * 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 - * the Free Software Foundation; under version 3 of the License. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_UTIL_H @@ -31,7 +25,7 @@ typedef bool_t(*DirForeachFunc) (const char * path, const char * basename, - gpointer user_data); + void * user_data); bool_t dir_foreach (const char * path, DirForeachFunc func, void * user_data); diff --git a/src/audacious/vis_runner.c b/src/audacious/vis_runner.c index a4a6e95..0a6bead 100644 --- a/src/audacious/vis_runner.c +++ b/src/audacious/vis_runner.c @@ -2,25 +2,24 @@ * vis_runner.c * Copyright 2009-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> #include <pthread.h> +#include <stdint.h> #include <string.h> #include "output.h" @@ -51,6 +50,9 @@ static void vis_node_free (VisNode * node) static bool_t send_audio (void * unused) { + /* call before locking mutex to avoid deadlock */ + int outputted = output_get_raw_time (); + pthread_mutex_lock (& mutex); if (! send_source) @@ -59,8 +61,6 @@ static bool_t send_audio (void * unused) return FALSE; } - int outputted = get_raw_output_time (); - VisNode * vis_node = NULL; VisNode * next; @@ -101,26 +101,7 @@ static bool_t send_clear (void * unused) return FALSE; } -static bool_t locked = FALSE; - -void vis_runner_lock (void) -{ - pthread_mutex_lock (& mutex); - locked = TRUE; -} - -void vis_runner_unlock (void) -{ - locked = FALSE; - pthread_mutex_unlock (& mutex); -} - -bool_t vis_runner_locked (void) -{ - return locked; -} - -void vis_runner_flush (void) +static void flush (void) { if (current_node) { @@ -135,7 +116,14 @@ void vis_runner_flush (void) clear_source = g_timeout_add (0, send_clear, NULL); } -void vis_runner_start_stop (bool_t new_playing, bool_t new_paused) +void vis_runner_flush (void) +{ + pthread_mutex_lock (& mutex); + flush (); + pthread_mutex_unlock (& mutex); +} + +static void start_stop (bool_t new_playing, bool_t new_paused) { playing = new_playing; paused = new_paused; @@ -154,16 +142,25 @@ void vis_runner_start_stop (bool_t new_playing, bool_t new_paused) } if (! active) - vis_runner_flush (); + flush (); else if (! paused) send_source = g_timeout_add (INTERVAL, send_audio, NULL); } +void vis_runner_start_stop (bool_t new_playing, bool_t new_paused) +{ + pthread_mutex_lock (& mutex); + start_stop (new_playing, new_paused); + pthread_mutex_unlock (& mutex); +} + void vis_runner_pass_audio (int time, float * data, int samples, int channels, int rate) { + pthread_mutex_lock (& mutex); + if (! active) - return; + goto UNLOCK; /* We can build a single node from multiple calls; we can also build * multiple nodes from the same call. If current_node is present, it was @@ -223,25 +220,15 @@ void vis_runner_pass_audio (int time, float * data, int samples, int g_queue_push_tail (& vis_list, current_node); current_node = NULL; } -} - -static void time_offset_cb (VisNode * vis_node, void * offset) -{ - vis_node->time += GPOINTER_TO_INT (offset); -} -void vis_runner_time_offset (int offset) -{ - if (current_node) - current_node->time += offset; - - g_queue_foreach (& vis_list, (GFunc) time_offset_cb, GINT_TO_POINTER (offset)); +UNLOCK: + pthread_mutex_unlock (& mutex); } void vis_runner_enable (bool_t enable) { pthread_mutex_lock (& mutex); enabled = enable; - vis_runner_start_stop (playing, paused); + start_stop (playing, paused); pthread_mutex_unlock (& mutex); } diff --git a/src/audacious/vis_runner.h b/src/audacious/vis_runner.h index c2a2149..4b08c5b 100644 --- a/src/audacious/vis_runner.h +++ b/src/audacious/vis_runner.h @@ -2,21 +2,19 @@ * vis_runner.h * Copyright 2009-2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUD_VIS_RUNNER_H @@ -24,20 +22,9 @@ #include <libaudcore/core.h> -/* When the decoder thread wants to send data to the vis runner, it must block - * the vis timeout before blocking output functions; otherwise, the vis timeout - * will hang up waiting for those output functions to be unblocked while the - * decoder thread hangs up waiting for the vis timeout to finish. */ -void vis_runner_lock (void); -void vis_runner_unlock (void); -bool_t vis_runner_locked (void); - void vis_runner_start_stop (bool_t playing, bool_t paused); -void vis_runner_pass_audio (int time, float * data, int samples, int - channels, int rate); -void vis_runner_time_offset (int offset); +void vis_runner_pass_audio (int time, float * data, int samples, int channels, int rate); void vis_runner_flush (void); - void vis_runner_enable (bool_t enable); #endif diff --git a/src/audacious/visualization.c b/src/audacious/visualization.c index 17f60c2..85ef430 100644 --- a/src/audacious/visualization.c +++ b/src/audacious/visualization.c @@ -2,21 +2,19 @@ * visualization.c * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> @@ -244,8 +242,6 @@ void vis_plugin_stop (PluginHandle * plugin) if (running) vis_unload (plugin); - if (vp->settings != NULL) - plugin_preferences_cleanup (vp->settings); if (vp->cleanup != NULL) vp->cleanup (); } diff --git a/src/audacious/visualization.h b/src/audacious/visualization.h index 78f6ac3..f57e86e 100644 --- a/src/audacious/visualization.h +++ b/src/audacious/visualization.h @@ -2,21 +2,19 @@ * visualization.h * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_VISUALIZATION_H diff --git a/src/audtool/audtool.h b/src/audtool/audtool.h index a1282fe..6db161e 100644 --- a/src/audtool/audtool.h +++ b/src/audtool/audtool.h @@ -1,32 +1,21 @@ /* - * Audtool2 - * Copyright (c) 2007 Audacious development team + * audtool.h + * Copyright 2005-2011 William Pitcock, George Averill, Giacomo Lozito, + * Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDTOOL_H diff --git a/src/audtool/examples/infoline.sh b/src/audtool/examples/infoline.sh deleted file mode 100755 index 96dd920..0000000 --- a/src/audtool/examples/infoline.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -UNUSED=0 -while [ $UNUSED -lt 1 ]; do - PLAYTIME=$(audtool current-song-output-length) - SONGTITLE=$(audtool current-song) - SONGLEN=$(audtool current-song-length) - echo -n "[>] $PLAYTIME $SONGTITLE ($SONGLEN) " - sleep 1 - printf "\r" -done diff --git a/src/audtool/examples/np.sh b/src/audtool/examples/np.sh deleted file mode 100755 index 60e4344..0000000 --- a/src/audtool/examples/np.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -SONGTITLE=$(audtool current-song) -SONGELAPSED=$(audtool current-song-output-length) -SONGLEN=$(audtool current-song-length) -MIME=$(file -ib "`audtool current-song-filename`") - -echo "np: $SONGTITLE [$MIME] ($SONGELAPSED/$SONGLEN)" diff --git a/src/audtool/handlers_equalizer.c b/src/audtool/handlers_equalizer.c index 22ae8ae..2a35ff0 100644 --- a/src/audtool/handlers_equalizer.c +++ b/src/audtool/handlers_equalizer.c @@ -1,32 +1,20 @@ /* - * Audtool2 - * Copyright (c) 2007 Audacious development team + * handlers_equalizer.c + * Copyright 2007-2008 Yoshiki Yazawa and Matti Hämäläinen * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdio.h> diff --git a/src/audtool/handlers_general.c b/src/audtool/handlers_general.c index a847626..5933e54 100644 --- a/src/audtool/handlers_general.c +++ b/src/audtool/handlers_general.c @@ -1,32 +1,21 @@ /* - * Audtool2 - * Copyright (c) 2007 Audacious development team + * handlers_general.c + * Copyright 2005-2008 George Averill, William Pitcock, Giacomo Lozito, and + * Matti Hämäläinen * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdlib.h> diff --git a/src/audtool/handlers_playback.c b/src/audtool/handlers_playback.c index b2d7bac..455924d 100644 --- a/src/audtool/handlers_playback.c +++ b/src/audtool/handlers_playback.c @@ -1,32 +1,20 @@ /* - * Audtool2 - * Copyright (c) 2007 Audacious development team + * handlers_playback.c + * Copyright 2005-2008 George Averill, William Pitcock, and Matti Hämäläinen * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdlib.h> diff --git a/src/audtool/handlers_playlist.c b/src/audtool/handlers_playlist.c index ada0461..b834bd7 100644 --- a/src/audtool/handlers_playlist.c +++ b/src/audtool/handlers_playlist.c @@ -1,32 +1,21 @@ /* - * Audtool2 - * Copyright (c) 2007 Audacious development team + * handlers_playlist.c + * Copyright 2005-2011 George Averill, William Pitcock, Yoshiki Yazawa, + * Matti Hämäläinen, and John Lindgren * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdlib.h> diff --git a/src/audtool/handlers_playqueue.c b/src/audtool/handlers_playqueue.c index ddcf2b8..275404e 100644 --- a/src/audtool/handlers_playqueue.c +++ b/src/audtool/handlers_playqueue.c @@ -1,32 +1,21 @@ /* - * Audtool2 - * Copyright (c) 2007 Audacious development team + * handlers_playqueue.c + * Copyright 2005-2008 George Averill, William Pitcock, Yoshiki Yazawa, and + * Matti Hämäläinen * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdlib.h> diff --git a/src/audtool/handlers_vitals.c b/src/audtool/handlers_vitals.c index 01b931a..f2325b4 100644 --- a/src/audtool/handlers_vitals.c +++ b/src/audtool/handlers_vitals.c @@ -1,32 +1,20 @@ /* - * Audtool2 - * Copyright (c) 2007 Audacious development team + * handlers_vitals.c + * Copyright 2005-2007 George Averill and William Pitcock * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdlib.h> diff --git a/src/audtool/main.c b/src/audtool/main.c index 8007117..6ef0745 100644 --- a/src/audtool/main.c +++ b/src/audtool/main.c @@ -1,32 +1,21 @@ /* - * Audtool - * Copyright (c) 2007 Audacious development team + * main.c + * Copyright 2005-2011 George Averill, William Pitcock, Yoshiki Yazawa, and + * John Lindgren * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdio.h> diff --git a/src/audtool/report.c b/src/audtool/report.c index d996a5d..ecb4791 100644 --- a/src/audtool/report.c +++ b/src/audtool/report.c @@ -1,32 +1,20 @@ /* - * Audtool2 - * Copyright (c) 2007 Audacious development team + * report.c + * Copyright 2007-2008 William Pitcock and Matti Hämäläinen * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions, and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdlib.h> diff --git a/src/libaudclient/Makefile b/src/libaudclient/Makefile index 475e583..52f720d 100644 --- a/src/libaudclient/Makefile +++ b/src/libaudclient/Makefile @@ -1,4 +1,4 @@ -LIB = ${LIB_PREFIX}audclient${LIB_SUFFIX} +SHARED_LIB = ${LIB_PREFIX}audclient${LIB_SUFFIX} LIB_MAJOR = 2 LIB_MINOR = 0 diff --git a/src/libaudclient/audctrl.c b/src/libaudclient/audctrl.c index d06a51b..530f877 100644 --- a/src/libaudclient/audctrl.c +++ b/src/libaudclient/audctrl.c @@ -1,18 +1,21 @@ /* - * Audacious: A cross-platform multimedia player - * Copyright (c) 2007 Ben Tucker + * audctrl.c + * Copyright 2007-2011 Ben Tucker, William Pitcock, Yoshiki Yazawa, + * Matti Hämäläinen, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdlib.h> diff --git a/src/libaudclient/audctrl.h b/src/libaudclient/audctrl.h index 518c3b7..6e316f8 100644 --- a/src/libaudclient/audctrl.h +++ b/src/libaudclient/audctrl.h @@ -1,20 +1,21 @@ /* - * Audacious: A cross-platform multimedia player - * Copyright (c) 2007 Ben Tucker + * audctrl.h + * Copyright 2007-2011 Ben Tucker, William Pitcock, Yoshiki Yazawa, + * Matti Hämäläinen, and John Lindgren * - * 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 - * the Free Software Foundation; under version 2 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDACIOUS_AUDCTRL_H diff --git a/src/libaudcore/Makefile b/src/libaudcore/Makefile index 0044d51..c823ae7 100644 --- a/src/libaudcore/Makefile +++ b/src/libaudcore/Makefile @@ -1,4 +1,4 @@ -LIB = ${LIB_PREFIX}audcore${LIB_SUFFIX} +SHARED_LIB = ${LIB_PREFIX}audcore${LIB_SUFFIX} LIB_MAJOR = 1 LIB_MINOR = 0 @@ -32,8 +32,7 @@ includesubdir = libaudcore CPPFLAGS := -I.. -I../.. \ ${CPPFLAGS} \ ${GLIB_CFLAGS} \ - ${PTHREAD_CFLAGS} CFLAGS += ${LIB_CFLAGS} -LIBS += ${PTHREAD_LIBS} ${GLIB_LIBS} -lm +LIBS += ${GLIB_LIBS} -lm diff --git a/src/libaudcore/audio.c b/src/libaudcore/audio.c index bc2f595..78aff88 100644 --- a/src/libaudcore/audio.c +++ b/src/libaudcore/audio.c @@ -1,6 +1,6 @@ /* * audio.c - * Copyright 2009-2011 John Lindgren + * Copyright 2009-2012 John Lindgren, Michał Lipski, and Anders Johansson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -19,6 +19,7 @@ #include <glib.h> #include <stdint.h> +#include <math.h> #include "audio.h" #include "config.h" @@ -28,7 +29,7 @@ static void NAME (const TYPE * in, float * out, int samples) \ { \ const TYPE * end = in + samples; \ while (in < end) \ - * out ++ = (TYPE) (SWAP (* in ++) - OFFSET) / (double) RANGE; \ + * out ++ = (TYPE) (SWAP (* in ++) - OFFSET) * (1.0 / (RANGE + 1.0)); \ } #define TO_INT_LOOP(NAME, TYPE, SWAP, OFFSET, RANGE) \ @@ -37,49 +38,49 @@ static void NAME (const float * in, TYPE * out, int samples) \ const float * end = in + samples; \ while (in < end) \ { \ - double f = * in ++; \ - * out ++ = SWAP (OFFSET + (TYPE) (CLAMP (f, -1, 1) * (double) RANGE)); \ + double f = (* in ++) * (RANGE + 1.0); \ + * out ++ = SWAP (OFFSET + (TYPE) round (CLAMP (f, -RANGE - 1, RANGE))); \ } \ } -static inline int8_t noop8 (int8_t i) {return i;} -static inline int16_t noop16 (int16_t i) {return i;} -static inline int32_t noop32 (int32_t i) {return i;} - -FROM_INT_LOOP (from_s8, int8_t, noop8, 0x00, 0x7f) -FROM_INT_LOOP (from_u8, int8_t, noop8, 0x80, 0x7f) -FROM_INT_LOOP (from_s16, int16_t, noop16, 0x0000, 0x7fff) -FROM_INT_LOOP (from_u16, int16_t, noop16, 0x8000, 0x7fff) -FROM_INT_LOOP (from_s24, int32_t, noop32, 0x000000, 0x7fffff) -FROM_INT_LOOP (from_u24, int32_t, noop32, 0x800000, 0x7fffff) -FROM_INT_LOOP (from_s32, int32_t, noop32, 0x00000000, 0x7fffffff) -FROM_INT_LOOP (from_u32, int32_t, noop32, 0x80000000, 0x7fffffff) - -TO_INT_LOOP (to_s8, int8_t, noop8, 0x00, 0x7f) -TO_INT_LOOP (to_u8, int8_t, noop8, 0x80, 0x7f) -TO_INT_LOOP (to_s16, int16_t, noop16, 0x0000, 0x7fff) -TO_INT_LOOP (to_u16, int16_t, noop16, 0x8000, 0x7fff) -TO_INT_LOOP (to_s24, int32_t, noop32, 0x000000, 0x7fffff) -TO_INT_LOOP (to_u24, int32_t, noop32, 0x800000, 0x7fffff) -TO_INT_LOOP (to_s32, int32_t, noop32, 0x00000000, 0x7fffffff) -TO_INT_LOOP (to_u32, int32_t, noop32, 0x80000000, 0x7fffffff) - -static inline int16_t swap16 (int16_t i) {return GUINT16_SWAP_LE_BE (i);} -static inline int32_t swap32 (int32_t i) {return GUINT32_SWAP_LE_BE (i);} - -FROM_INT_LOOP (from_s16_swap, int16_t, swap16, 0x0000, 0x7fff) -FROM_INT_LOOP (from_u16_swap, int16_t, swap16, 0x8000, 0x7fff) -FROM_INT_LOOP (from_s24_swap, int32_t, swap32, 0x000000, 0x7fffff) -FROM_INT_LOOP (from_u24_swap, int32_t, swap32, 0x800000, 0x7fffff) -FROM_INT_LOOP (from_s32_swap, int32_t, swap32, 0x00000000, 0x7fffffff) -FROM_INT_LOOP (from_u32_swap, int32_t, swap32, 0x80000000, 0x7fffffff) - -TO_INT_LOOP (to_s16_swap, int16_t, swap16, 0x0000, 0x7fff) -TO_INT_LOOP (to_u16_swap, int16_t, swap16, 0x8000, 0x7fff) -TO_INT_LOOP (to_s24_swap, int32_t, swap32, 0x000000, 0x7fffff) -TO_INT_LOOP (to_u24_swap, int32_t, swap32, 0x800000, 0x7fffff) -TO_INT_LOOP (to_s32_swap, int32_t, swap32, 0x00000000, 0x7fffffff) -TO_INT_LOOP (to_u32_swap, int32_t, swap32, 0x80000000, 0x7fffffff) +static inline int8_t NOOP8 (int8_t i) {return i;} +static inline int16_t NOOP16 (int16_t i) {return i;} +static inline int32_t NOOP32 (int32_t i) {return i;} + +FROM_INT_LOOP (from_s8, int8_t, NOOP8, 0x00, 0x7f) +FROM_INT_LOOP (from_u8, int8_t, NOOP8, 0x80, 0x7f) +FROM_INT_LOOP (from_s16, int16_t, NOOP16, 0x0000, 0x7fff) +FROM_INT_LOOP (from_u16, int16_t, NOOP16, 0x8000, 0x7fff) +FROM_INT_LOOP (from_s24, int32_t, NOOP32, 0x000000, 0x7fffff) +FROM_INT_LOOP (from_u24, int32_t, NOOP32, 0x800000, 0x7fffff) +FROM_INT_LOOP (from_s32, int32_t, NOOP32, 0x00000000, 0x7fffffff) +FROM_INT_LOOP (from_u32, int32_t, NOOP32, 0x80000000, 0x7fffffff) + +TO_INT_LOOP (to_s8, int8_t, NOOP8, 0x00, 0x7f) +TO_INT_LOOP (to_u8, int8_t, NOOP8, 0x80, 0x7f) +TO_INT_LOOP (to_s16, int16_t, NOOP16, 0x0000, 0x7fff) +TO_INT_LOOP (to_u16, int16_t, NOOP16, 0x8000, 0x7fff) +TO_INT_LOOP (to_s24, int32_t, NOOP32, 0x000000, 0x7fffff) +TO_INT_LOOP (to_u24, int32_t, NOOP32, 0x800000, 0x7fffff) +TO_INT_LOOP (to_s32, int32_t, NOOP32, 0x00000000, 0x7fffffff) +TO_INT_LOOP (to_u32, int32_t, NOOP32, 0x80000000, 0x7fffffff) + +static inline int16_t SWAP16 (int16_t i) {return GUINT16_SWAP_LE_BE (i);} +static inline int32_t SWAP32 (int32_t i) {return GUINT32_SWAP_LE_BE (i);} + +FROM_INT_LOOP (from_s16_swap, int16_t, SWAP16, 0x0000, 0x7fff) +FROM_INT_LOOP (from_u16_swap, int16_t, SWAP16, 0x8000, 0x7fff) +FROM_INT_LOOP (from_s24_swap, int32_t, SWAP32, 0x000000, 0x7fffff) +FROM_INT_LOOP (from_u24_swap, int32_t, SWAP32, 0x800000, 0x7fffff) +FROM_INT_LOOP (from_s32_swap, int32_t, SWAP32, 0x00000000, 0x7fffffff) +FROM_INT_LOOP (from_u32_swap, int32_t, SWAP32, 0x80000000, 0x7fffffff) + +TO_INT_LOOP (to_s16_swap, int16_t, SWAP16, 0x0000, 0x7fff) +TO_INT_LOOP (to_u16_swap, int16_t, SWAP16, 0x8000, 0x7fff) +TO_INT_LOOP (to_s24_swap, int32_t, SWAP32, 0x000000, 0x7fffff) +TO_INT_LOOP (to_u24_swap, int32_t, SWAP32, 0x800000, 0x7fffff) +TO_INT_LOOP (to_s32_swap, int32_t, SWAP32, 0x00000000, 0x7fffffff) +TO_INT_LOOP (to_u32_swap, int32_t, SWAP32, 0x80000000, 0x7fffffff) typedef void (* FromFunc) (const void * in, float * out, int samples); typedef void (* ToFunc) (const float * in, void * out, int samples); @@ -168,3 +169,31 @@ EXPORT void audio_amplify (float * data, int channels, int frames, float * facto } } } + +/* linear approximation of y = sin(x) */ +/* contributed by Anders Johansson */ +EXPORT void audio_soft_clip (float * data, int samples) +{ + float * end = data + samples; + + while (data < end) + { + float x = * data; + float y = fabsf (x); + + if (y <= 0.4) + ; /* (0, 0.4) -> (0, 0.4) */ + else if (y <= 0.7) + y = 0.8 * y + 0.08; /* (0.4, 0.7) -> (0.4, 0.64) */ + else if (y <= 1.0) + y = 0.7 * y + 0.15; /* (0.7, 1) -> (0.64, 0.85) */ + else if (y <= 1.3) + y = 0.4 * y + 0.45; /* (1, 1.3) -> (0.85, 0.97) */ + else if (y <= 1.5) + y = 0.15 * y + 0.775; /* (1.3, 1.5) -> (0.97, 1) */ + else + y = 1.0; /* (1.5, inf) -> 1 */ + + * data ++ = (x > 0) ? y : -y; + } +} diff --git a/src/libaudcore/audio.h.in b/src/libaudcore/audio.h.in index d7b2cae..290f717 100644 --- a/src/libaudcore/audio.h.in +++ b/src/libaudcore/audio.h.in @@ -49,5 +49,6 @@ enum { void audio_from_int (const void * in, int format, float * out, int samples); void audio_to_int (const float * in, void * out, int format, int samples); void audio_amplify (float * data, int channels, int frames, float * factors); +void audio_soft_clip (float * data, int samples); #endif /* LIBAUDCORE_AUDIO_H */ diff --git a/src/libaudcore/audstrings.c b/src/libaudcore/audstrings.c index 8c836d2..ec5b4b0 100644 --- a/src/libaudcore/audstrings.c +++ b/src/libaudcore/audstrings.c @@ -74,10 +74,10 @@ EXPORT char * str_to_utf8_full (const char * str, int len, int * bytes_read, int return str_to_utf8_full_impl (str, len, bytes_read, bytes_written); } -EXPORT void string_replace_char (char * string, char old_str, char new_str) +EXPORT void string_replace_char (char * string, char old_c, char new_c) { - while ((string = strchr (string, old_str)) != NULL) - * string = new_str; + while ((string = strchr (string, old_c))) + * string ++ = new_c; } /* Percent-decodes up to <len> bytes of <str> to <out>, which must be large diff --git a/src/libaudcore/audstrings.h b/src/libaudcore/audstrings.h index 363daf1..01fc670 100644 --- a/src/libaudcore/audstrings.h +++ b/src/libaudcore/audstrings.h @@ -31,7 +31,7 @@ void str_set_utf8_impl (char * (* stu_impl) (const char *), char * str_to_utf8 (const char * str); char * str_to_utf8_full (const char * str, int len, int * bytes_read, int * bytes_written); -void string_replace_char (char * string, char old_str, char new_str); +void string_replace_char (char * string, char old_c, char new_c); void str_decode_percent (const char * str, int len, char * out); void str_encode_percent (const char * str, int len, char * out); diff --git a/src/libaudcore/core.h b/src/libaudcore/core.h index d8bb57a..76934a0 100644 --- a/src/libaudcore/core.h +++ b/src/libaudcore/core.h @@ -22,6 +22,13 @@ /* #define STRPOOL_DEBUG */ +#undef NULL +#ifdef __cplusplus /* *sigh* */ +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif + /* "bool_t" means "int" for compatibility with GLib */ #undef bool_t #define bool_t int @@ -31,6 +38,17 @@ #undef TRUE #define TRUE ((bool_t) 1) +#undef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#undef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#undef CLAMP +#define CLAMP(a,min,max) ((a) < (min) ? (min) : (a) > (max) ? (max) : (a)) + +#define SPRINTF(s,...) \ + char s[snprintf (NULL, 0, __VA_ARGS__) + 1]; \ + snprintf (s, sizeof s, __VA_ARGS__); + /* Simple sanity check to catch (1) strings that are still in use after their * reference count has dropped to zero and (2) strings that should have been * pooled but never were. If the check fails, the program is aborted. */ diff --git a/src/libaudcore/tuple.c b/src/libaudcore/tuple.c index 8ea0633..e3fa2ed 100644 --- a/src/libaudcore/tuple.c +++ b/src/libaudcore/tuple.c @@ -3,20 +3,19 @@ * Copyright 2007-2011 William Pitcock, Christian Birchinger, Matti Hämäläinen, * Giacomo Lozito, Eugene Zagidullin, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /** diff --git a/src/libaudcore/tuple.h b/src/libaudcore/tuple.h index f202c1d..d787391 100644 --- a/src/libaudcore/tuple.h +++ b/src/libaudcore/tuple.h @@ -3,20 +3,19 @@ * Copyright 2007-2011 William Pitcock, Christian Birchinger, Matti Hämäläinen, * Giacomo Lozito, Eugene Zagidullin, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /** diff --git a/src/libaudcore/tuple_compiler.c b/src/libaudcore/tuple_compiler.c index eeef443..d59feb8 100644 --- a/src/libaudcore/tuple_compiler.c +++ b/src/libaudcore/tuple_compiler.c @@ -1,22 +1,21 @@ /* - * Audacious - Tuplez compiler + * tuple_compiler.c * Copyright (c) 2007 Matti 'ccr' Hämäläinen * Copyright (c) 2011 John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /* diff --git a/src/libaudcore/tuple_compiler.h b/src/libaudcore/tuple_compiler.h index 9aaacbf..c5f3aa3 100644 --- a/src/libaudcore/tuple_compiler.h +++ b/src/libaudcore/tuple_compiler.h @@ -1,21 +1,20 @@ /* - * Audacious - Tuplez compiler + * tuple_compiler.h * Copyright (c) 2007 Matti 'ccr' Hämäläinen * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef LIBAUDCORE_TUPLE_COMPILER_H diff --git a/src/libaudcore/vfs.c b/src/libaudcore/vfs.c index ded6056..84ed572 100644 --- a/src/libaudcore/vfs.c +++ b/src/libaudcore/vfs.c @@ -1,22 +1,21 @@ /* - * vfs.c - * Copyright 2006-2011 William Pitcock, Daniel Barkalow, Ralf Ertzinger, - * Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren + * vfs.c + * Copyright 2006-2011 William Pitcock, Daniel Barkalow, Ralf Ertzinger, + * Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/libaudcore/vfs.h b/src/libaudcore/vfs.h index 24179ea..face5fb 100644 --- a/src/libaudcore/vfs.h +++ b/src/libaudcore/vfs.h @@ -3,20 +3,19 @@ * Copyright 2006-2011 William Pitcock, Daniel Barkalow, Ralf Ertzinger, * Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /** * @file vfs.h @@ -32,6 +31,13 @@ #include <libaudcore/core.h> +/* equivalent to G_FILE_TEST_XXX */ +#define VFS_IS_REGULAR (1 << 0) +#define VFS_IS_SYMLINK (1 << 1) +#define VFS_IS_DIR (1 << 2) +#define VFS_IS_EXECUTABLE (1 << 3) +#define VFS_EXISTS (1 << 4) + /** @struct VFSFile */ typedef struct _VFSFile VFSFile; /** @struct VFSConstructor */ diff --git a/src/libaudcore/vfs_common.c b/src/libaudcore/vfs_common.c index 42efb93..384e4eb 100644 --- a/src/libaudcore/vfs_common.c +++ b/src/libaudcore/vfs_common.c @@ -3,20 +3,19 @@ * Copyright 2006-2010 Tony Vroon, William Pitcock, Maciej Grela, * Matti Hämäläinen, and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/libaudgui/Makefile b/src/libaudgui/Makefile index 875af02..8246dd3 100644 --- a/src/libaudgui/Makefile +++ b/src/libaudgui/Makefile @@ -1,4 +1,4 @@ -LIB = ${LIB_PREFIX}audgui${LIB_SUFFIX} +SHARED_LIB = ${LIB_PREFIX}audgui${LIB_SUFFIX} LIB_MAJOR = 1 LIB_MINOR = 0 @@ -15,12 +15,12 @@ SRCS = about.c \ playlists.c \ queue-manager.c \ ui_fileopener.c \ - ui_urlopener.c \ ui_jumptotrack.c \ ui_jumptotrack_cache.c \ icons-stock.c \ ui_playlist_manager.c \ urilist.c \ + url-opener.c \ util.c INCLUDES = libaudgui.h \ diff --git a/src/libaudgui/about.c b/src/libaudgui/about.c index 80eb61b..eee71ef 100644 --- a/src/libaudgui/about.c +++ b/src/libaudgui/about.c @@ -19,38 +19,24 @@ #include <gtk/gtk.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include <audacious/misc.h> #include "config.h" #include "libaudgui-gtk.h" -static GtkWidget * about_window; - -static GtkTextBuffer * create_text_buffer (const char * const * items) -{ - GString * string = g_string_new (""); - - for (; items[0] || items[1]; items ++) - { - if (items[0]) - g_string_append (string, _(items[0])); +static const char about_text[] = + "<big><b>Audacious " VERSION "</b></big>\n" + "Copyright © 2001-2012 Audacious developers and others"; - g_string_append_c (string, '\n'); - } +static const char website[] = "http://audacious-media-player.org"; - GtkTextBuffer * buffer = gtk_text_buffer_new (NULL); - gtk_text_buffer_set_text (buffer, string->str, string->len - 1); - g_string_free (string, TRUE); - return buffer; -} +static GtkWidget * about_window; -static GtkWidget * create_credits_notebook (const char * const * credits, - const char * const * translators) +static GtkWidget * create_credits_notebook (const char * credits, const char * license) { - const char * titles[2] = {_("Credits"), _("Translators")}; - const char * const * lists[2] = {credits, translators}; + const char * titles[2] = {_("Credits"), _("License")}; + const char * text[2] = {credits, license}; GtkWidget * notebook = gtk_notebook_new (); @@ -59,11 +45,11 @@ static GtkWidget * create_credits_notebook (const char * const * credits, GtkWidget * label = gtk_label_new (titles[i]); GtkWidget * scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, - GTK_SHADOW_IN); gtk_widget_set_size_request (scrolled, -1, 200); - GtkWidget * text = gtk_text_view_new_with_buffer (create_text_buffer (lists[i])); + GtkTextBuffer * buffer = gtk_text_buffer_new (NULL); + gtk_text_buffer_set_text (buffer, text[i], -1); + GtkWidget * text = gtk_text_view_new_with_buffer (buffer); gtk_text_view_set_editable ((GtkTextView *) text, FALSE); gtk_text_view_set_cursor_visible ((GtkTextView *) text, FALSE); gtk_text_view_set_left_margin ((GtkTextView *) text, 6); @@ -84,9 +70,6 @@ EXPORT void audgui_show_about_window (void) return; } - const char * brief, * const * credits, * const * translators; - aud_get_audacious_credits (& brief, & credits, & translators); - about_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title ((GtkWindow *) about_window, _("About Audacious")); gtk_window_set_resizable ((GtkWindow *) about_window, FALSE); @@ -96,26 +79,41 @@ EXPORT void audgui_show_about_window (void) g_signal_connect (about_window, "destroy", (GCallback) gtk_widget_destroyed, & about_window); - GtkWidget * vbox = gtk_vbox_new (FALSE, 6); + GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_add ((GtkContainer *) about_window, vbox); - char * name = g_strdup_printf ("%s/images/about-logo.png", aud_get_path - (AUD_PATH_DATA_DIR)); - GtkWidget * image = gtk_image_new_from_file (name); + SPRINTF (logo_path, "%s/images/about-logo.png", aud_get_path (AUD_PATH_DATA_DIR)); + GtkWidget * image = gtk_image_new_from_file (logo_path); gtk_box_pack_start ((GtkBox *) vbox, image, FALSE, FALSE, 0); - g_free (name); - char * markup = g_strdup_printf (brief, VERSION); GtkWidget * label = gtk_label_new (NULL); - gtk_label_set_markup ((GtkLabel *) label, markup); + gtk_label_set_markup ((GtkLabel *) label, about_text); gtk_label_set_justify ((GtkLabel *) label, GTK_JUSTIFY_CENTER); gtk_box_pack_start ((GtkBox *) vbox, label, FALSE, FALSE, 0); - g_free (markup); - GtkWidget * exp = gtk_expander_new (_("Credits")); - GtkWidget * notebook = create_credits_notebook (credits, translators); - gtk_container_add ((GtkContainer *) exp, notebook); - gtk_box_pack_start ((GtkBox *) vbox, exp, TRUE, TRUE, 0); + GtkWidget * button = gtk_link_button_new (website); + gtk_widget_set_halign (button, GTK_ALIGN_CENTER); + gtk_box_pack_start ((GtkBox *) vbox, button, FALSE, FALSE, 0); + + char * credits, * license; + + SPRINTF (credits_path, "%s/AUTHORS", aud_get_path (AUD_PATH_DATA_DIR)); + if (! g_file_get_contents (credits_path, & credits, NULL, NULL)) + credits = g_strdup_printf ("Unable to load %s; check your installation.", credits_path); + + SPRINTF (license_path, "%s/COPYING", aud_get_path (AUD_PATH_DATA_DIR)); + if (! g_file_get_contents (license_path, & license, NULL, NULL)) + license = g_strdup_printf ("Unable to load %s; check your installation.", license_path); + + g_strchomp (credits); + g_strchomp (license); + + GtkWidget * notebook = create_credits_notebook (credits, license); + gtk_widget_set_size_request (notebook, 600, 250); + gtk_box_pack_start ((GtkBox *) vbox, notebook, TRUE, TRUE, 0); + + g_free (credits); + g_free (license); gtk_widget_show_all (about_window); } diff --git a/src/libaudgui/confirm.c b/src/libaudgui/confirm.c index 74297f2..2224bd2 100644 --- a/src/libaudgui/confirm.c +++ b/src/libaudgui/confirm.c @@ -19,7 +19,6 @@ #include <gtk/gtk.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include <audacious/misc.h> #include <audacious/playlist.h> @@ -59,14 +58,15 @@ EXPORT void audgui_confirm_playlist_delete (int playlist) window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_type_hint ((GtkWindow *) window, GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_title ((GtkWindow *) window, _("Close Playlist")); gtk_window_set_resizable ((GtkWindow *) window, FALSE); gtk_container_set_border_width ((GtkContainer *) window, 6); audgui_destroy_on_escape (window); - vbox = gtk_vbox_new (FALSE, 6); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_add ((GtkContainer *) window, vbox); - hbox = gtk_hbox_new (FALSE, 6); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0); gtk_box_pack_start ((GtkBox *) hbox, gtk_image_new_from_stock @@ -83,14 +83,14 @@ EXPORT void audgui_confirm_playlist_delete (int playlist) gtk_widget_set_size_request (label, 320, -1); gtk_box_pack_start ((GtkBox *) hbox, label, TRUE, FALSE, 0); - hbox = gtk_hbox_new (FALSE, 6); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0); button = gtk_check_button_new_with_mnemonic (_("_Don't show this message again")); gtk_box_pack_start ((GtkBox *) hbox, button, FALSE, FALSE, 0); g_signal_connect (button, "toggled", (GCallback) no_confirm_cb, NULL); - hbox = gtk_hbox_new (FALSE, 6); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0); button = gtk_button_new_from_stock (GTK_STOCK_NO); diff --git a/src/libaudgui/effects-menu.c b/src/libaudgui/effects-menu.c index b7d9f78..3334abf 100644 --- a/src/libaudgui/effects-menu.c +++ b/src/libaudgui/effects-menu.c @@ -52,9 +52,7 @@ static void settings_cb (GtkMenuItem * settings, PluginHandle * plugin) if (! aud_plugin_get_enabled (plugin)) return; - Plugin * header = aud_plugin_get_header (plugin); - g_return_if_fail (header != NULL); - header->configure (); + aud_plugin_do_configure (plugin); } static bool_t add_item_cb (PluginHandle * plugin, GtkWidget * menu) diff --git a/src/libaudgui/equalizer.c b/src/libaudgui/equalizer.c index 9841db0..063f974 100644 --- a/src/libaudgui/equalizer.c +++ b/src/libaudgui/equalizer.c @@ -91,13 +91,14 @@ static GtkWidget * create_slider (const char * name, int band) { GtkWidget * vbox, * slider, * label; - vbox = gtk_vbox_new (FALSE, 6); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); label = gtk_label_new (name); gtk_label_set_angle ((GtkLabel *) label, 90); gtk_box_pack_start ((GtkBox *) vbox, label, TRUE, FALSE, 0); - slider = gtk_vscale_new_with_range (-EQUALIZER_MAX_GAIN, EQUALIZER_MAX_GAIN, 1); + slider = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, + -EQUALIZER_MAX_GAIN, EQUALIZER_MAX_GAIN, 1); gtk_scale_set_draw_value ((GtkScale *) slider, TRUE); gtk_scale_set_value_pos ((GtkScale *) slider, GTK_POS_BOTTOM); gtk_widget_set_size_request (slider, -1, 120); @@ -135,16 +136,17 @@ static GtkWidget * create_window (void) gtk_widget_hide_on_delete, NULL); audgui_hide_on_escape (window); - vbox = gtk_vbox_new (FALSE, 6); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_add ((GtkContainer *) window, vbox); gtk_box_pack_start ((GtkBox *) vbox, create_on_off (), FALSE, FALSE, 0); - hbox = gtk_hbox_new (FALSE, 6); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox, hbox, FALSE, FALSE, 0); gtk_box_pack_start ((GtkBox *) hbox, create_slider (_("Preamp"), -1), FALSE, FALSE, 0); - gtk_box_pack_start ((GtkBox *) hbox, gtk_vseparator_new (), FALSE, FALSE, 0); + gtk_box_pack_start ((GtkBox *) hbox, + gtk_separator_new (GTK_ORIENTATION_VERTICAL), FALSE, FALSE, 0); for (i = 0; i < AUD_EQUALIZER_NBANDS; i ++) gtk_box_pack_start ((GtkBox *) hbox, create_slider (_(names[i]), i), FALSE, FALSE, 0); diff --git a/src/libaudgui/icons-stock.c b/src/libaudgui/icons-stock.c index 6c767d6..7bdf2c1 100644 --- a/src/libaudgui/icons-stock.c +++ b/src/libaudgui/icons-stock.c @@ -2,20 +2,19 @@ * icons-stock.c * Copyright 2007-2010 Michael Färber and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <gtk/gtk.h> @@ -48,6 +47,8 @@ audgui_register_stock_icons(void) { GtkIconFactory *iconfactory = gtk_icon_factory_new(); + load_stock_icon(AUD_STOCK_AUDACIOUS, + "audacious.png", iconfactory); load_stock_icon(AUD_STOCK_PLAYLIST, "menu_playlist.png", iconfactory); load_stock_icon(AUD_STOCK_PLUGIN, diff --git a/src/libaudgui/infopopup.c b/src/libaudgui/infopopup.c index d51ae7b..f702b90 100644 --- a/src/libaudgui/infopopup.c +++ b/src/libaudgui/infopopup.c @@ -21,7 +21,6 @@ #include <string.h> #include <audacious/drct.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include <audacious/misc.h> #include <audacious/playlist.h> @@ -135,7 +134,7 @@ static void infopopup_progress_stop (void) (0)); } -static void infopopup_add_category (GtkWidget * infopopup_data_table, +static void infopopup_add_category (GtkWidget * infopopup_data_grid, const char * category, const char * header_data, const char * label_data, int position) { @@ -145,8 +144,8 @@ static void infopopup_add_category (GtkWidget * infopopup_data_table, gtk_misc_set_alignment ((GtkMisc *) infopopup_data_info_header, 0, 0.5); gtk_misc_set_alignment ((GtkMisc *) infopopup_data_info_label, 0, 0.5); - gtk_misc_set_padding ((GtkMisc *) infopopup_data_info_header, 0, 3); - gtk_misc_set_padding ((GtkMisc *) infopopup_data_info_label, 0, 3); + gtk_misc_set_padding ((GtkMisc *) infopopup_data_info_header, 0, 1); + gtk_misc_set_padding ((GtkMisc *) infopopup_data_info_label, 0, 1); markup = g_markup_printf_escaped ("<span style=\"italic\">%s</span>", category); @@ -157,26 +156,26 @@ static void infopopup_add_category (GtkWidget * infopopup_data_table, infopopup_data_info_header); g_object_set_data ((GObject *) infopopup, label_data, infopopup_data_info_label); - gtk_table_attach ((GtkTable *) infopopup_data_table, - infopopup_data_info_header, 0, 1, position, position + 1, GTK_FILL, 0, 0, 0); - gtk_table_attach ((GtkTable *) infopopup_data_table, - infopopup_data_info_label, 1, 2, position, position + 1, GTK_FILL, 0, 0, 0); + gtk_grid_attach ((GtkGrid *) infopopup_data_grid, + infopopup_data_info_header, 0, position, 1, 1); + gtk_grid_attach ((GtkGrid *) infopopup_data_grid, + infopopup_data_info_label, 1, position, 1, 1); } static void infopopup_create (void) { GtkWidget * infopopup_hbox; GtkWidget * infopopup_data_image; - GtkWidget * infopopup_data_table; + GtkWidget * infopopup_data_grid; GtkWidget * infopopup_progress; infopopup = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_set_type_hint ((GtkWindow *) infopopup, GDK_WINDOW_TYPE_HINT_TOOLTIP); gtk_window_set_decorated ((GtkWindow *) infopopup, FALSE); - gtk_container_set_border_width ((GtkContainer *) infopopup, 6); + gtk_container_set_border_width ((GtkContainer *) infopopup, 4); - infopopup_hbox = gtk_hbox_new (FALSE, 0); + infopopup_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_container_add ((GtkContainer *) infopopup, infopopup_hbox); infopopup_data_image = gtk_image_new (); @@ -185,37 +184,32 @@ static void infopopup_create (void) gtk_box_pack_start ((GtkBox *) infopopup_hbox, infopopup_data_image, FALSE, FALSE, 0); - gtk_box_pack_start ((GtkBox *) infopopup_hbox, gtk_vseparator_new (), FALSE, - FALSE, 6); - - infopopup_data_table = gtk_table_new (8, 2, FALSE); - gtk_table_set_row_spacings ((GtkTable *) infopopup_data_table, 0); - gtk_table_set_col_spacings ((GtkTable *) infopopup_data_table, 6); - gtk_box_pack_start ((GtkBox *) infopopup_hbox, infopopup_data_table, TRUE, + infopopup_data_grid = gtk_grid_new (); + gtk_grid_set_column_spacing ((GtkGrid *) infopopup_data_grid, 6); + gtk_box_pack_start ((GtkBox *) infopopup_hbox, infopopup_data_grid, TRUE, TRUE, 0); - infopopup_add_category (infopopup_data_table, _("Title"), "header_title", + infopopup_add_category (infopopup_data_grid, _("Title"), "header_title", "label_title", 0); - infopopup_add_category (infopopup_data_table, _("Artist"), "header_artist", + infopopup_add_category (infopopup_data_grid, _("Artist"), "header_artist", "label_artist", 1); - infopopup_add_category (infopopup_data_table, _("Album"), "header_album", + infopopup_add_category (infopopup_data_grid, _("Album"), "header_album", "label_album", 2); - infopopup_add_category (infopopup_data_table, _("Genre"), "header_genre", - "label_genre", 3); - infopopup_add_category (infopopup_data_table, _("Year"), "header_year", + infopopup_add_category (infopopup_data_grid, _("Genre"), "header_genre", + "label_genre",3); + infopopup_add_category (infopopup_data_grid, _("Year"), "header_year", "label_year", 4); - infopopup_add_category (infopopup_data_table, _("Track Number"), + infopopup_add_category (infopopup_data_grid, _("Track"), "header_tracknum", "label_tracknum", 5); - infopopup_add_category (infopopup_data_table, _("Track Length"), + infopopup_add_category (infopopup_data_grid, _("Length"), "header_tracklen", "label_tracklen", 6); - gtk_table_set_row_spacing ((GtkTable *) infopopup_data_table, 6, 6); - /* track progress */ infopopup_progress = gtk_progress_bar_new (); + gtk_widget_set_margin_top (infopopup_progress, 6); gtk_progress_bar_set_text ((GtkProgressBar *) infopopup_progress, ""); - gtk_table_attach ((GtkTable *) infopopup_data_table, infopopup_progress, 0, - 2, 7, 8, GTK_FILL, 0, 0, 0); + gtk_grid_attach ((GtkGrid *) infopopup_data_grid, + infopopup_progress, 0, 7, 2, 1); g_object_set_data ((GObject *) infopopup, "file", NULL); g_object_set_data ((GObject *) infopopup, "progressbar", infopopup_progress); infopopup_progress_init (); @@ -313,7 +307,7 @@ static void infopopup_show (int playlist, int entry, const char * filename, infopopup_progress_cb (NULL); } - gdk_window_get_pointer (gdk_get_default_root_window (), & x, & y, NULL); + audgui_get_mouse_coords (NULL, & x, & y); gtk_window_get_size ((GtkWindow *) infopopup, & w, & h); /* If we show the popup right under the cursor, the underlying window gets diff --git a/src/libaudgui/infowin.c b/src/libaudgui/infowin.c index c069b5f..4c6390e 100644 --- a/src/libaudgui/infowin.c +++ b/src/libaudgui/infowin.c @@ -3,27 +3,26 @@ * Copyright 2006-2011 William Pitcock, Tomasz Moń, Eugene Zagidullin, and * John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <gtk/gtk.h> #include <stdarg.h> #include <stdlib.h> +#include <string.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include <audacious/misc.h> #include <audacious/playlist.h> @@ -309,8 +308,8 @@ static void create_infowin (void) GtkWidget * label_quality_label; GtkWidget * label_bitrate_label; GtkWidget * codec_hbox; - GtkWidget * codec_table; - GtkWidget * table1; + GtkWidget * codec_grid; + GtkWidget * grid1; GtkWidget * bbox_close; GtkWidget * btn_close; GtkWidget * alignment; @@ -321,17 +320,20 @@ static void create_infowin (void) gtk_window_set_type_hint ((GtkWindow *) infowin, GDK_WINDOW_TYPE_HINT_DIALOG); - vbox0 = gtk_vbox_new (FALSE, 0); + vbox0 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add ((GtkContainer *) infowin, vbox0); - hbox = gtk_hbox_new (FALSE, 6); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox0, hbox, TRUE, TRUE, 0); - vbox2 = gtk_vbox_new (FALSE, 6); + vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_box_pack_start ((GtkBox *) hbox, vbox2, TRUE, TRUE, 0); + GtkWidget * vbox3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start ((GtkBox *) vbox2, vbox3, TRUE, FALSE, 0); + image_artwork = gtk_image_new (); - gtk_box_pack_start ((GtkBox *) vbox2, image_artwork, TRUE, TRUE, 0); + gtk_box_pack_start ((GtkBox *) vbox3, image_artwork, FALSE, FALSE, 0); location_text = gtk_label_new (""); gtk_widget_set_size_request (location_text, 200, -1); @@ -339,15 +341,15 @@ static void create_infowin (void) gtk_label_set_line_wrap_mode ((GtkLabel *) location_text, PANGO_WRAP_WORD_CHAR); gtk_label_set_selectable ((GtkLabel *) location_text, TRUE); - gtk_box_pack_start ((GtkBox *) vbox2, location_text, FALSE, FALSE, 0); + gtk_box_pack_start ((GtkBox *) vbox3, location_text, FALSE, FALSE, 0); - codec_hbox = gtk_hbox_new (FALSE, 6); + codec_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) vbox2, codec_hbox, FALSE, FALSE, 0); - codec_table = gtk_table_new(3, 2, FALSE); - gtk_table_set_row_spacings ((GtkTable *) codec_table, 3); - gtk_table_set_col_spacings ((GtkTable *) codec_table, 12); - gtk_box_pack_start ((GtkBox *) codec_hbox, codec_table, FALSE, FALSE, 0); + codec_grid = gtk_grid_new (); + gtk_grid_set_row_spacing ((GtkGrid *) codec_grid, 3); + gtk_grid_set_column_spacing ((GtkGrid *) codec_grid, 12); + gtk_box_pack_start ((GtkBox *) codec_hbox, codec_grid, FALSE, FALSE, 0); label_format = gtk_label_new (_("<span size=\"small\">Format:</span>")); gtk_label_set_use_markup ((GtkLabel *) label_format, TRUE); @@ -370,20 +372,14 @@ static void create_infowin (void) gtk_label_set_use_markup ((GtkLabel *) label_bitrate, TRUE); gtk_misc_set_alignment ((GtkMisc *) label_bitrate, 0, 0.5); - gtk_table_attach ((GtkTable *) codec_table, label_format, 0, 1, 0, 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_table_attach ((GtkTable *) codec_table, label_format_name, 1, 2, 0, 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_table_attach ((GtkTable *) codec_table, label_quality_label, 0, 1, 1, 2, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_table_attach ((GtkTable *) codec_table, label_quality, 1, 2, 1, 2, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_table_attach ((GtkTable *) codec_table, label_bitrate_label, 0, 1, 2, 3, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_table_attach ((GtkTable *) codec_table, label_bitrate, 1, 2, 2, 3, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - - vbox2 = gtk_vbox_new (FALSE, 0); + gtk_grid_attach ((GtkGrid *) codec_grid, label_format, 0, 0, 1, 1); + gtk_grid_attach ((GtkGrid *) codec_grid, label_format_name, 1, 0, 1, 1); + gtk_grid_attach ((GtkGrid *) codec_grid, label_quality_label, 0, 1, 1, 1); + gtk_grid_attach ((GtkGrid *) codec_grid, label_quality, 1, 1, 1, 1); + gtk_grid_attach ((GtkGrid *) codec_grid, label_bitrate_label, 0, 2, 1, 1); + gtk_grid_attach ((GtkGrid *) codec_grid, label_bitrate, 1, 2, 1, 1); + + vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start ((GtkBox *) hbox, vbox2, TRUE, TRUE, 0); label_title = gtk_label_new (_("<span size=\"small\">Title</span>")); @@ -451,33 +447,30 @@ static void create_infowin (void) alignment = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_box_pack_start ((GtkBox *) vbox2, alignment, FALSE, FALSE, 0); gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 6, 0, 0); - table1 = gtk_table_new (2, 2, FALSE); - gtk_container_add ((GtkContainer *) alignment, table1); - gtk_table_set_col_spacings ((GtkTable *) table1, 6); + grid1 = gtk_grid_new (); + gtk_grid_set_column_homogeneous ((GtkGrid *) grid1, TRUE); + gtk_container_add ((GtkContainer *) alignment, grid1); + gtk_grid_set_column_spacing ((GtkGrid *) grid1, 6); label_year = gtk_label_new (_("<span size=\"small\">Year</span>")); - gtk_table_attach ((GtkTable *) table1, label_year, 0, 1, 0, 1, GTK_FILL, 0, - 0, 0); + gtk_grid_attach ((GtkGrid *) grid1, label_year, 0, 0, 1, 1); gtk_label_set_use_markup ((GtkLabel *) label_year, TRUE); gtk_misc_set_alignment ((GtkMisc *) label_year, 0, 0.5); entry_year = gtk_entry_new (); - gtk_table_attach ((GtkTable *) table1, entry_year, 0, 1, 1, 2, GTK_EXPAND | - GTK_FILL, 0, 0, 0); + gtk_grid_attach ((GtkGrid *) grid1, entry_year, 0, 1, 1, 1); g_signal_connect (entry_year, "changed", (GCallback) entry_changed, NULL); label_track = gtk_label_new (_("<span size=\"small\">Track Number</span>")); - gtk_table_attach ((GtkTable *) table1, label_track, 1, 2, 0, 1, GTK_FILL, 0, - 0, 0); + gtk_grid_attach ((GtkGrid *) grid1, label_track, 1, 0, 1, 1); gtk_label_set_use_markup ((GtkLabel *) label_track, TRUE); gtk_misc_set_alignment ((GtkMisc *) label_track, 0, 0.5); entry_track = gtk_entry_new (); - gtk_table_attach ((GtkTable *) table1, entry_track, 1, 2, 1, 2, GTK_EXPAND | - GTK_FILL, 0, 0, 0); + gtk_grid_attach ((GtkGrid *) grid1, entry_track, 1, 1, 1, 1); g_signal_connect (entry_track, "changed", (GCallback) entry_changed, NULL); - hbox_status_and_bbox = gtk_hbox_new (FALSE, 0); + hbox_status_and_bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start ((GtkBox *) vbox0, hbox_status_and_bbox, FALSE, FALSE, 0); label_mini_status = gtk_label_new ("<span size=\"small\"></span>"); @@ -486,7 +479,7 @@ static void create_infowin (void) gtk_box_pack_start ((GtkBox *) hbox_status_and_bbox, label_mini_status, TRUE, TRUE, 0); - bbox_close = gtk_hbutton_box_new (); + bbox_close = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); gtk_box_set_spacing ((GtkBox *) bbox_close, 6); gtk_box_pack_start ((GtkBox *) hbox_status_and_bbox, bbox_close, FALSE, FALSE, 0); diff --git a/src/libaudgui/init.c b/src/libaudgui/init.c index ef00c97..82b1232 100644 --- a/src/libaudgui/init.c +++ b/src/libaudgui/init.c @@ -62,10 +62,12 @@ EXPORT void audgui_cleanup (void) hook_dissociate ("playlist position", playlist_position_cb); audgui_hide_equalizer_window (); + audgui_jump_to_time_cleanup (); audgui_jump_to_track_hide (); audgui_pixbuf_uncache (); audgui_playlist_manager_cleanup (); audgui_queue_manager_cleanup (); + audgui_url_opener_cleanup (); _aud_api_table = NULL; } diff --git a/src/libaudgui/init.h b/src/libaudgui/init.h index ac0c945..1018d0a 100644 --- a/src/libaudgui/init.h +++ b/src/libaudgui/init.h @@ -23,11 +23,17 @@ void audgui_init (AudAPITable * table); void audgui_cleanup (void); +/* jump-to-time.c */ +void audgui_jump_to_time_cleanup (void); + /* queue-manager.c */ void audgui_queue_manager_cleanup (void); /* ui_playlist_manager.c */ void audgui_playlist_manager_cleanup (void); +/* url-opener.c */ +void audgui_url_opener_cleanup (void); + /* util.c */ void audgui_pixbuf_uncache (void); diff --git a/src/libaudgui/jump-to-time.c b/src/libaudgui/jump-to-time.c index 671f773..391e32d 100644 --- a/src/libaudgui/jump-to-time.c +++ b/src/libaudgui/jump-to-time.c @@ -1,113 +1,89 @@ /* * jump-to-time.c - * Copyright 1998-2003 XMMS development team - * Copyright 2003-2004 BMP development team - * Copyright 2011 John Lindgren + * Copyright 2012 John Lindgren * - * 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 - * the Free Software Foundation; under version 2 or version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdio.h> #include <gtk/gtk.h> #include <audacious/drct.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include "config.h" +#include "init.h" #include "libaudgui.h" -#include "libaudgui-gtk.h" -static GtkWidget * window = NULL; +static GtkWidget * window; -static void jump_to_time_cb (GtkWidget * widget, GtkWidget * entry) +static void response_cb (GtkWidget * dialog, int response) { - unsigned int min = 0, sec = 0; - int params = sscanf (gtk_entry_get_text ((GtkEntry *) entry), "%u:%u", & min, - & sec); - - int time; - if (params == 2) - time = 60 * min + sec; - else if (params == 1) - time = min; - else - return; + if (response == GTK_RESPONSE_ACCEPT) + { + GtkWidget * entry = g_object_get_data ((GObject *) dialog, "entry"); + const char * text = gtk_entry_get_text ((GtkEntry *) entry); + unsigned minutes, seconds; - if (aud_drct_get_playing ()) - aud_drct_seek (1000 * time); + if (sscanf (text, "%u:%u", & minutes, & seconds) == 2 && aud_drct_get_playing ()) + aud_drct_seek ((minutes * 60 + seconds) * 1000); + } - if (window) - gtk_widget_destroy (window); + gtk_widget_destroy (dialog); } EXPORT void audgui_jump_to_time (void) { - if (! aud_drct_get_playing ()) - return; - if (window) - { - gtk_window_present ((GtkWindow *) window); - return; - } + gtk_widget_destroy (window); - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - g_signal_connect (window, "destroy", (GCallback) gtk_widget_destroyed, - & window); - gtk_window_set_type_hint ((GtkWindow *) window, GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_title ((GtkWindow *) window, _("Jump to Time")); + window = gtk_dialog_new_with_buttons (_("Jump to Time"), NULL, 0, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_JUMP_TO, + GTK_RESPONSE_ACCEPT, NULL); + gtk_widget_set_size_request (window, 200, -1); gtk_window_set_resizable ((GtkWindow *) window, FALSE); - gtk_container_set_border_width ((GtkContainer *) window, 6); - audgui_destroy_on_escape (window); - - GtkWidget * vbox = gtk_vbox_new (FALSE, 6); - gtk_container_add ((GtkContainer *) window, vbox); + gtk_dialog_set_default_response ((GtkDialog *) window, GTK_RESPONSE_ACCEPT); - GtkWidget * hbox_new = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start ((GtkBox *) vbox, hbox_new, FALSE, FALSE, 0); + GtkWidget * box = gtk_dialog_get_content_area ((GtkDialog *) window); - GtkWidget * time_entry = gtk_entry_new (); - gtk_entry_set_activates_default ((GtkEntry *) time_entry, TRUE); - gtk_box_pack_start ((GtkBox *) hbox_new, time_entry, FALSE, FALSE, 0); + GtkWidget * label = gtk_label_new (_("Enter time (minutes:seconds):")); + gtk_misc_set_alignment ((GtkMisc *) label, 0, 0); + gtk_box_pack_start ((GtkBox *) box, label, FALSE, FALSE, 0); - GtkWidget * label = gtk_label_new (_("mm:ss")); - gtk_box_pack_start ((GtkBox *) hbox_new, label, FALSE, FALSE, 0); + GtkWidget * entry = gtk_entry_new (); + gtk_entry_set_activates_default ((GtkEntry *) entry, TRUE); + gtk_box_pack_start ((GtkBox *) box, entry, FALSE, FALSE, 0); - GtkWidget * bbox = gtk_hbutton_box_new (); - gtk_box_pack_start ((GtkBox *) vbox, bbox, TRUE, TRUE, 0); - gtk_button_box_set_layout ((GtkButtonBox *) bbox, GTK_BUTTONBOX_END); - gtk_box_set_spacing ((GtkBox *) bbox, 6); - - GtkWidget * cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL); - gtk_container_add ((GtkContainer *) bbox, cancel); - g_signal_connect_swapped (cancel, "clicked", (GCallback) gtk_widget_destroy, - window); + if (aud_drct_get_playing ()) + { + char buf[16]; + int time = aud_drct_get_time () / 1000; + snprintf (buf, sizeof buf, "%u:%02u", time / 60, time % 60); + gtk_entry_set_text ((GtkEntry *) entry, buf); + } - GtkWidget * jump = gtk_button_new_from_stock (GTK_STOCK_JUMP_TO); - gtk_widget_set_can_default (jump, TRUE); - gtk_container_add ((GtkContainer *) bbox, jump); - g_signal_connect (jump, "clicked", (GCallback) jump_to_time_cb, time_entry); + g_object_set_data ((GObject *) window, "entry", entry); - unsigned int tindex = aud_drct_get_time () / 1000; - char time_str[10]; - snprintf (time_str, sizeof time_str, "%u:%2.2u", tindex / 60, tindex % 60); - gtk_entry_set_text ((GtkEntry *) time_entry, time_str); - gtk_editable_select_region ((GtkEditable *) time_entry, 0, -1); + g_signal_connect (window, "response", (GCallback) response_cb, NULL); + g_signal_connect (window, "destroy", (GCallback) gtk_widget_destroyed, & window); gtk_widget_show_all (window); - gtk_widget_grab_default (jump); +} + +void audgui_jump_to_time_cleanup (void) +{ + if (window) + gtk_widget_destroy (window); } diff --git a/src/libaudgui/libaudgui-gtk.h b/src/libaudgui/libaudgui-gtk.h index c54fd36..25c81d3 100644 --- a/src/libaudgui/libaudgui-gtk.h +++ b/src/libaudgui/libaudgui-gtk.h @@ -32,6 +32,8 @@ GtkWidget * audgui_create_vis_menu (void); GtkWidget * audgui_create_iface_menu (void); /* util.c */ +int audgui_get_digit_width (GtkWidget * widget); +void audgui_get_mouse_coords (GtkWidget * widget, int * x, int * y); void audgui_hide_on_delete (GtkWidget * widget); void audgui_hide_on_escape (GtkWidget * widget); void audgui_destroy_on_escape (GtkWidget * widget); diff --git a/src/libaudgui/libaudgui.h b/src/libaudgui/libaudgui.h index 3f4aebc..3aeec3a 100644 --- a/src/libaudgui/libaudgui.h +++ b/src/libaudgui/libaudgui.h @@ -2,20 +2,19 @@ * libaudgui.h * Copyright 2007-2009 Giacomo Lozito and Tomasz Moń - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef LIBAUDGUI_H @@ -24,6 +23,7 @@ #include <libaudcore/core.h> /* macro defines for Audacious stock icons */ +#define AUD_STOCK_AUDACIOUS "aud-audacious" #define AUD_STOCK_PLAYLIST "aud-playlist" #define AUD_STOCK_PLUGIN "aud-plugin" #define AUD_STOCK_QUEUETOGGLE "aud-queuetoggle" diff --git a/src/libaudgui/list.c b/src/libaudgui/list.c index 7ead4bd..b40aaea 100644 --- a/src/libaudgui/list.c +++ b/src/libaudgui/list.c @@ -1,6 +1,6 @@ /* * list.c - * Copyright 2011 John Lindgren + * Copyright 2011-2012 John Lindgren and Michał Lipski * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,23 +17,26 @@ * the use of this software. */ +#include <stddef.h> +#include <gtk/gtk.h> + #include "config.h" +#include "libaudgui-gtk.h" #include "list.h" -#include <audacious/gtk-compat.h> - -#define CHAR_WIDTH 12 -#define SPACING 4 - enum {HIGHLIGHT_COLUMN, RESERVED_COLUMNS}; +#define MODEL_HAS_CB(m, cb) \ + ((m)->cbs_size > offsetof (AudguiListCallbacks, cb) && (m)->cbs->cb) #define PATH_IS_SELECTED(w, p) (gtk_tree_selection_path_is_selected \ (gtk_tree_view_get_selection ((GtkTreeView *) (w)), (p))) typedef struct { GObject parent; const AudguiListCallbacks * cbs; + int cbs_size; void * user; + int charwidth; int rows, highlight; int columns; GList * column_types; @@ -227,8 +230,8 @@ static bool_t button_press_cb (GtkWidget * widget, GdkEventButton * event, gtk_tree_view_get_path_at_pos ((GtkTreeView *) widget, event->x, event->y, & path, NULL, NULL, NULL); - if (event->type == GDK_BUTTON_PRESS && event->button == 3 && - model->cbs->right_click) + if (event->type == GDK_BUTTON_PRESS && event->button == 3 + && MODEL_HAS_CB (model, right_click)) { /* Only allow GTK to select this row if it is not already selected. We * don't want to clear a multiple selection. */ @@ -293,6 +296,36 @@ static bool_t key_press_cb (GtkWidget * widget, GdkEventKey * event, ListModel * return FALSE; } +static bool_t motion_notify_cb (GtkWidget * widget, GdkEventMotion * event, ListModel * model) +{ + if (MODEL_HAS_CB (model, mouse_motion)) + { + int x, y; + gtk_tree_view_convert_bin_window_to_widget_coords ((GtkTreeView *) + widget, event->x, event->y, & x, & y); + + int row = audgui_list_row_at_point (widget, x, y); + model->cbs->mouse_motion (model->user, event, row); + } + + return FALSE; +} + +static bool_t leave_notify_cb (GtkWidget * widget, GdkEventMotion * event, ListModel * model) +{ + if (MODEL_HAS_CB (model, mouse_leave)) + { + int x, y; + gtk_tree_view_convert_bin_window_to_widget_coords ((GtkTreeView *) + widget, event->x, event->y, & x, & y); + + int row = audgui_list_row_at_point (widget, x, y); + model->cbs->mouse_leave (model->user, event, row); + } + + return FALSE; +} + /* ==== DRAG AND DROP ==== */ static void drag_begin (GtkWidget * widget, GdkDragContext * context, @@ -327,7 +360,7 @@ static void drag_data_get (GtkWidget * widget, GdkDragContext * context, static int calc_drop_row (ListModel * model, GtkWidget * widget, int x, int y) { - int row = audgui_list_row_at_point (widget, x, y); + int row = audgui_list_row_at_point_rounded (widget, x, y); if (row < 0) row = model->rows; return row; @@ -348,7 +381,7 @@ static bool_t autoscroll (GtkWidget * widget) ListModel * model = (ListModel *) gtk_tree_view_get_model ((GtkTreeView *) widget); - GtkAdjustment * adj = gtk_tree_view_get_vadjustment ((GtkTreeView *) widget); + GtkAdjustment * adj = gtk_scrollable_get_vadjustment ((GtkScrollable *) widget); if (! adj) return FALSE; @@ -386,9 +419,9 @@ static bool_t drag_motion (GtkWidget * widget, GdkDragContext * context, * not to clear it. */ model->frozen = FALSE; - if (model->dragging && model->cbs->shift_rows) /* dragging within same list */ + if (model->dragging && MODEL_HAS_CB (model, shift_rows)) /* dragging within same list */ gdk_drag_status (context, GDK_ACTION_MOVE, time); - else if (model->cbs->data_type) /* cross-widget dragging */ + else if (MODEL_HAS_CB (model, data_type)) /* cross-widget dragging */ gdk_drag_status (context, GDK_ACTION_COPY, time); else return FALSE; @@ -418,9 +451,11 @@ static bool_t drag_motion (GtkWidget * widget, GdkDragContext * context, gtk_tree_view_convert_widget_to_bin_window_coords ((GtkTreeView *) widget, x, y, & x, & y); - if (y >= 0 && y < 48) + int hotspot = MIN (height / 4, 24); + + if (y >= 0 && y < hotspot) start_autoscroll (model, widget, -2); - else if (y >= height - 48 && y < height) + else if (y >= height - hotspot && y < height) start_autoscroll (model, widget, 2); else stop_autoscroll (model); @@ -445,14 +480,14 @@ static bool_t drag_drop (GtkWidget * widget, GdkDragContext * context, int x, bool_t success = TRUE; int row = calc_drop_row (model, widget, x, y); - if (model->dragging && model->cbs->shift_rows) /* dragging within same list */ + if (model->dragging && MODEL_HAS_CB (model, shift_rows)) /* dragging within same list */ { if (model->clicked_row >= 0 && model->clicked_row < model->rows) model->cbs->shift_rows (model->user, model->clicked_row, row); else success = FALSE; } - else if (model->cbs->data_type) /* cross-widget dragging */ + else if (MODEL_HAS_CB (model, data_type)) /* cross-widget dragging */ { model->receive_row = row; gtk_drag_get_data (widget, context, gdk_atom_intern @@ -510,17 +545,14 @@ static void update_selection (GtkWidget * list, ListModel * model, int at, model->blocked = FALSE; } -EXPORT GtkWidget * audgui_list_new (const AudguiListCallbacks * cbs, void * user, - int rows) +EXPORT GtkWidget * audgui_list_new_real (const AudguiListCallbacks * cbs, int cbs_size, + void * user, int rows) { g_return_val_if_fail (cbs->get_value, NULL); - if (cbs->get_selected) - g_return_val_if_fail (cbs->set_selected && cbs->select_all, NULL); - if (cbs->data_type) - g_return_val_if_fail (cbs->get_data && cbs->receive_data, NULL); ListModel * model = (ListModel *) g_object_new (list_model_get_type (), NULL); model->cbs = cbs; + model->cbs_size = cbs_size; model->user = user; model->rows = rows; model->highlight = -1; @@ -538,7 +570,10 @@ EXPORT GtkWidget * audgui_list_new (const AudguiListCallbacks * cbs, void * user gtk_tree_view_set_fixed_height_mode ((GtkTreeView *) list, TRUE); g_signal_connect_swapped (list, "destroy", (GCallback) destroy_cb, model); - if (cbs->get_selected) + model->charwidth = audgui_get_digit_width (list); + + if (MODEL_HAS_CB (model, get_selected) && MODEL_HAS_CB (model, set_selected) + && MODEL_HAS_CB (model, select_all)) { GtkTreeSelection * sel = gtk_tree_view_get_selection ((GtkTreeView *) list); @@ -549,14 +584,19 @@ EXPORT GtkWidget * audgui_list_new (const AudguiListCallbacks * cbs, void * user update_selection (list, model, 0, rows); } - if (cbs->activate_row) + if (MODEL_HAS_CB (model, activate_row)) g_signal_connect (list, "row-activated", (GCallback) activate_cb, model); g_signal_connect (list, "button-press-event", (GCallback) button_press_cb, model); g_signal_connect (list, "button-release-event", (GCallback) button_release_cb, model); g_signal_connect (list, "key-press-event", (GCallback) key_press_cb, model); + g_signal_connect (list, "motion-notify-event", (GCallback) motion_notify_cb, model); + g_signal_connect (list, "leave-notify-event", (GCallback) leave_notify_cb, model); + + bool_t supports_drag = FALSE; - if (cbs->data_type) + if (MODEL_HAS_CB (model, data_type) && MODEL_HAS_CB (model, get_data) && + MODEL_HAS_CB (model, receive_data)) { const GtkTargetEntry target = {(char *) cbs->data_type, 0, 0}; @@ -568,14 +608,17 @@ EXPORT GtkWidget * audgui_list_new (const AudguiListCallbacks * cbs, void * user model); g_signal_connect (list, "drag-data-received", (GCallback) drag_data_received, model); + + supports_drag = TRUE; } - else if (cbs->shift_rows) + else if (MODEL_HAS_CB (model, shift_rows)) { gtk_drag_source_set (list, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY); gtk_drag_dest_set (list, 0, NULL, 0, GDK_ACTION_COPY); + supports_drag = TRUE; } - if (cbs->data_type || cbs->shift_rows) + if (supports_drag) { g_signal_connect (list, "drag-begin", (GCallback) drag_begin, model); g_signal_connect (list, "drag-end", (GCallback) drag_end, model); @@ -611,16 +654,23 @@ EXPORT void audgui_list_add_column (GtkWidget * list, const char * title, HIGHLIGHT_COLUMN, NULL); gtk_tree_view_column_set_sizing (tree_column, GTK_TREE_VIEW_COLUMN_FIXED); + int pad1, pad2, pad3; + gtk_widget_style_get (list, "horizontal-separator", & pad1, "focus-line-width", & pad2, NULL); + gtk_cell_renderer_get_padding (renderer, & pad3, NULL); + int padding = pad1 + 2 * pad2 + 2 * pad3; + if (width < 1) { - gtk_tree_view_column_set_fixed_width (tree_column, 6 * CHAR_WIDTH + SPACING); + gtk_tree_view_column_set_fixed_width (tree_column, + 6 * model->charwidth + model->charwidth / 2 + padding); gtk_tree_view_column_set_expand (tree_column, TRUE); g_object_set ((GObject *) renderer, "ellipsize-set", TRUE, "ellipsize", PANGO_ELLIPSIZE_END, NULL); } else { - gtk_tree_view_column_set_fixed_width (tree_column, width * CHAR_WIDTH + SPACING); + gtk_tree_view_column_set_fixed_width (tree_column, + width * model->charwidth + model->charwidth / 2 + padding); g_object_set ((GObject *) renderer, "xalign", (float) 1, NULL); } @@ -679,6 +729,19 @@ EXPORT void audgui_list_delete_rows (GtkWidget * list, int at, int rows) ((GtkTreeView *) list); g_return_if_fail (at >= 0 && rows >= 0 && at + rows <= model->rows); + /* If we delete the last selected row, GtkTreeView tries to be helpful by + * selecting another one near it. As a workaround, detect this case and + * clear the selection when it occurs. */ + GtkTreeSelection * sel = gtk_tree_view_get_selection ((GtkTreeView *) list); + int selected = gtk_tree_selection_count_selected_rows (sel); + + for (int i = at; i < at + rows; i ++) + { + GtkTreeIter iter = {.user_data = GINT_TO_POINTER (i)}; + if (gtk_tree_selection_iter_is_selected (sel, & iter)) + selected --; + } + model->rows -= rows; if (model->highlight >= at + rows) model->highlight -= rows; @@ -691,6 +754,9 @@ EXPORT void audgui_list_delete_rows (GtkWidget * list, int at, int rows) while (rows --) gtk_tree_model_row_deleted ((GtkTreeModel *) model, path); + if (! selected) + gtk_tree_selection_unselect_all (sel); + gtk_tree_path_free (path); model->blocked = FALSE; } @@ -765,14 +831,29 @@ EXPORT void audgui_list_set_focus (GtkWidget * list, int row) EXPORT int audgui_list_row_at_point (GtkWidget * list, int x, int y) { - ListModel * model = (ListModel *) gtk_tree_view_get_model ((GtkTreeView *) - list); + ListModel * model = (ListModel *) gtk_tree_view_get_model ((GtkTreeView *) list); + + GtkTreePath * path = NULL; + gtk_tree_view_convert_widget_to_bin_window_coords ((GtkTreeView *) list, x, y, & x, & y); + gtk_tree_view_get_path_at_pos ((GtkTreeView *) list, x, y, & path, NULL, NULL, NULL); + + if (! path) + return -1; + + int row = gtk_tree_path_get_indices (path)[0]; + g_return_val_if_fail (row >= 0 && row < model->rows, -1); + + gtk_tree_path_free (path); + return row; +} + +EXPORT int audgui_list_row_at_point_rounded (GtkWidget * list, int x, int y) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model ((GtkTreeView *) list); GtkTreePath * path = NULL; - gtk_tree_view_convert_widget_to_bin_window_coords ((GtkTreeView *) list, x, - y, & x, & y); - gtk_tree_view_get_path_at_pos ((GtkTreeView *) list, x, y, & path, NULL, - NULL, NULL); + gtk_tree_view_convert_widget_to_bin_window_coords ((GtkTreeView *) list, x, y, & x, & y); + gtk_tree_view_get_path_at_pos ((GtkTreeView *) list, x, y, & path, NULL, NULL, NULL); if (! path) return -1; @@ -781,8 +862,7 @@ EXPORT int audgui_list_row_at_point (GtkWidget * list, int x, int y) g_return_val_if_fail (row >= 0 && row < model->rows, -1); GdkRectangle rect; - gtk_tree_view_get_background_area ((GtkTreeView *) list, path, NULL, - & rect); + gtk_tree_view_get_background_area ((GtkTreeView *) list, path, NULL, & rect); if (y > rect.y + rect.height / 2) row ++; diff --git a/src/libaudgui/list.h b/src/libaudgui/list.h index 4f92d6a..68091f1 100644 --- a/src/libaudgui/list.h +++ b/src/libaudgui/list.h @@ -1,6 +1,6 @@ /* * list.h - * Copyright 2011 John Lindgren + * Copyright 2011-2012 John Lindgren and Michał Lipski * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -23,6 +23,11 @@ #include <gtk/gtk.h> #include <libaudcore/core.h> +/* New callbacks should be added to the end of this struct. The + * audgui_list_new() macro tells us the size of the callback struct as it was + * defined when the caller code was compiled, allowing us to expand the struct + * without breaking backward compatibility. */ + typedef struct { void (* get_value) (void * user, int row, int column, GValue * value); @@ -40,10 +45,17 @@ typedef struct { void (* get_data) (void * user, void * * data, int * length); /* data will be freed */ void (* receive_data) (void * user, int row, const void * data, int length); + + void (* mouse_motion) (void * user, GdkEventMotion * event, int row); /* optional */ + void (* mouse_leave) (void * user, GdkEventMotion * event, int row); /* optional */ } AudguiListCallbacks; -GtkWidget * audgui_list_new (const AudguiListCallbacks * cbs, void * user, - int rows); +GtkWidget * audgui_list_new_real (const AudguiListCallbacks * cbs, int cbs_size, + void * user, int rows); + +#define audgui_list_new(c, u, r) \ + audgui_list_new_real (c, sizeof (AudguiListCallbacks), u, r) + void * audgui_list_get_user (GtkWidget * list); void audgui_list_add_column (GtkWidget * list, const char * title, int column, GType type, int width); @@ -60,5 +72,6 @@ int audgui_list_get_focus (GtkWidget * list); void audgui_list_set_focus (GtkWidget * list, int row); int audgui_list_row_at_point (GtkWidget * list, int x, int y); +int audgui_list_row_at_point_rounded (GtkWidget * list, int x, int y); #endif diff --git a/src/libaudgui/queue-manager.c b/src/libaudgui/queue-manager.c index f9d1c69..b8a4e4d 100644 --- a/src/libaudgui/queue-manager.c +++ b/src/libaudgui/queue-manager.c @@ -20,7 +20,6 @@ #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include <audacious/playlist.h> #include <libaudcore/hook.h> @@ -161,11 +160,11 @@ static void destroy_cb (void) static bool_t keypress_cb (GtkWidget * widget, GdkEventKey * event) { - if (event->keyval == GDK_A && (event->state & GDK_CONTROL_MASK)) + if (event->keyval == GDK_KEY_A && (event->state & GDK_CONTROL_MASK)) select_all (NULL, TRUE); - else if (event->keyval == GDK_Delete) + else if (event->keyval == GDK_KEY_Delete) remove_selected (); - else if (event->keyval == GDK_Escape) + else if (event->keyval == GDK_KEY_Escape) gtk_widget_destroy (qm_win); else return FALSE; diff --git a/src/libaudgui/ui_fileopener.c b/src/libaudgui/ui_fileopener.c index 1a8331f..2a740f7 100644 --- a/src/libaudgui/ui_fileopener.c +++ b/src/libaudgui/ui_fileopener.c @@ -2,27 +2,25 @@ * ui_fileopener.c * Copyright 2007-2011 Michael Färber and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <gtk/gtk.h> #include <audacious/i18n.h> #include <audacious/drct.h> -#include <audacious/gtk-compat.h> #include <audacious/misc.h> #include "config.h" @@ -118,7 +116,7 @@ run_filebrowser_gtk2style(bool_t play_button, bool_t show) gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_container_set_border_width(GTK_CONTAINER(window), 10); - vbox = gtk_vbox_new(FALSE, 0); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(window), vbox); chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_OPEN); @@ -131,7 +129,7 @@ run_filebrowser_gtk2style(bool_t play_button, bool_t show) gtk_box_pack_start(GTK_BOX(vbox), chooser, TRUE, TRUE, 3); - hbox = gtk_hbox_new(TRUE, 0); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); const char * option = play_button ? "close_dialog_open" : "close_dialog_add"; @@ -141,7 +139,7 @@ run_filebrowser_gtk2style(bool_t play_button, bool_t show) g_signal_connect (toggle, "toggled", (GCallback) toggled_cb, (void *) option); gtk_box_pack_start(GTK_BOX(hbox), toggle, TRUE, TRUE, 3); - bbox = gtk_hbutton_box_new(); + bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); gtk_box_set_spacing(GTK_BOX(bbox), 6); gtk_box_pack_end(GTK_BOX(hbox), bbox, TRUE, TRUE, 3); diff --git a/src/libaudgui/ui_jumptotrack.c b/src/libaudgui/ui_jumptotrack.c index e3f348d..094697a 100644 --- a/src/libaudgui/ui_jumptotrack.c +++ b/src/libaudgui/ui_jumptotrack.c @@ -1,30 +1,26 @@ /* * ui_jumptotrack.c - * Copyright 1998-2003 XMMS development team - * Copyright 2003-2004 BMP development team * Copyright 2007-2011 Yoshiki Yazawa and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> #include <audacious/drct.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include <audacious/misc.h> #include <audacious/playlist.h> @@ -92,8 +88,8 @@ static void do_jump (void) return; int playlist = aud_playlist_get_active (); - aud_playlist_set_playing (playlist); aud_playlist_set_position (playlist, entry); + aud_playlist_set_playing (playlist); aud_drct_play (); if (aud_get_bool ("audgui", "close_jtf_dialog")) @@ -143,7 +139,7 @@ static void selection_changed (void) static bool_t keypress_cb (GtkWidget * widget, GdkEventKey * event) { - if (event->keyval == GDK_Escape) + if (event->keyval == GDK_KEY_Escape) { audgui_jump_to_track_hide(); return TRUE; @@ -271,10 +267,12 @@ static void create_window (void) gtk_container_set_border_width(GTK_CONTAINER(jump_to_track_win), 10); gtk_window_set_default_size(GTK_WINDOW(jump_to_track_win), 600, 500); - GtkWidget * vbox = gtk_vbox_new (FALSE, 5); + GtkWidget * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); gtk_container_add(GTK_CONTAINER(jump_to_track_win), vbox); treeview = audgui_list_new (& callbacks, NULL, 0); + gtk_tree_view_set_headers_visible ((GtkTreeView *) treeview, FALSE); + audgui_list_add_column (treeview, NULL, 0, G_TYPE_INT, 7); audgui_list_add_column (treeview, NULL, 1, G_TYPE_STRING, -1); @@ -282,7 +280,7 @@ static void create_window (void) "changed", (GCallback) selection_changed, NULL); g_signal_connect (treeview, "row-activated", (GCallback) do_jump, NULL); - GtkWidget * hbox = gtk_hbox_new (FALSE, 3); + GtkWidget * hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); /* filter box */ @@ -313,12 +311,12 @@ static void create_window (void) GtkWidget * scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_container_add(GTK_CONTAINER(scrollwin), treeview); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0); - GtkWidget * bbox = gtk_hbutton_box_new (); + GtkWidget * bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); gtk_box_set_spacing(GTK_BOX(bbox), 4); gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); diff --git a/src/libaudgui/ui_jumptotrack_cache.c b/src/libaudgui/ui_jumptotrack_cache.c index 5c124b1..0a355c9 100644 --- a/src/libaudgui/ui_jumptotrack_cache.c +++ b/src/libaudgui/ui_jumptotrack_cache.c @@ -2,20 +2,19 @@ * ui_jumptotrack_cache.c * Copyright 2008-2011 Jussi Judin and John Lindgren * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/libaudgui/ui_jumptotrack_cache.h b/src/libaudgui/ui_jumptotrack_cache.h index 26c8114..8452845 100644 --- a/src/libaudgui/ui_jumptotrack_cache.h +++ b/src/libaudgui/ui_jumptotrack_cache.h @@ -2,20 +2,19 @@ * ui_jumptotrack_cache.h * Copyright 2008 Jussi Judin * - * 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 - * the Free Software Foundation; under version 3 of the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * This program 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. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses>. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef LIBAUDGUI_UI_JUMPTOTRACK_CACHE_H diff --git a/src/libaudgui/ui_playlist_manager.c b/src/libaudgui/ui_playlist_manager.c index 5f2df1d..03e5fbc 100644 --- a/src/libaudgui/ui_playlist_manager.c +++ b/src/libaudgui/ui_playlist_manager.c @@ -17,11 +17,12 @@ * the use of this software. */ +#include <string.h> #include <gtk/gtk.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include <audacious/misc.h> +#include <audacious/drct.h> #include <audacious/playlist.h> #include <libaudcore/hook.h> @@ -32,6 +33,7 @@ #include "list.h" static GtkWidget * playman_win = NULL; +static void activate_row (void * user, int row); static void save_position (GtkWidget * window) { @@ -52,18 +54,23 @@ static bool_t hide_cb (GtkWidget * window) return TRUE; } +static void play_cb (void) +{ + activate_row (NULL, aud_playlist_get_active ()); +} + static void rename_cb (void) { audgui_show_playlist_rename (aud_playlist_get_active ()); } -static void new_cb (GtkButton * button, void * unused) +static void new_cb (void) { aud_playlist_insert (aud_playlist_get_active () + 1); aud_playlist_set_active (aud_playlist_get_active () + 1); } -static void delete_cb (GtkButton * button, GtkWidget * list) +static void delete_cb (void) { audgui_confirm_playlist_delete (aud_playlist_get_active ()); } @@ -107,6 +114,7 @@ static void select_all (void * user, bool_t selected) static void activate_row (void * user, int row) { aud_playlist_set_active (row); + aud_drct_play_playlist (row); if (aud_get_bool ("audgui", "playlist_manager_close_on_activate")) hide_cb (playman_win); @@ -235,27 +243,27 @@ static void close_on_activate_cb (GtkToggleButton * toggle) EXPORT void audgui_playlist_manager (void) { - GtkWidget *playman_vbox; + GtkWidget * playman_vbox; GtkWidget * playman_pl_lv, * playman_pl_lv_sw; - GtkWidget *playman_bbar_hbbox; - GtkWidget * rename_button, * new_button, * delete_button; - GtkWidget * hbox, * button; + GtkWidget * playman_button_hbox; + GtkWidget * new_button, * delete_button, * rename_button, * play_button; + GtkWidget * hbox, * check_button; GdkGeometry playman_win_hints; - if ( playman_win != NULL ) + if (playman_win) { - gtk_window_present( GTK_WINDOW(playman_win) ); + gtk_window_present ((GtkWindow *) playman_win); return; } - playman_win = gtk_window_new( GTK_WINDOW_TOPLEVEL ); - gtk_window_set_type_hint( GTK_WINDOW(playman_win), GDK_WINDOW_TYPE_HINT_DIALOG ); - gtk_window_set_title( GTK_WINDOW(playman_win), _("Playlist Manager") ); + playman_win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint ((GtkWindow *) playman_win, GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_title ((GtkWindow *) playman_win, _("Playlist Manager")); gtk_container_set_border_width ((GtkContainer *) playman_win, 6); playman_win_hints.min_width = 400; playman_win_hints.min_height = 250; - gtk_window_set_geometry_hints( GTK_WINDOW(playman_win) , GTK_WIDGET(playman_win) , - &playman_win_hints , GDK_HINT_MIN_SIZE ); + gtk_window_set_geometry_hints ((GtkWindow *) playman_win, playman_win, + &playman_win_hints , GDK_HINT_MIN_SIZE); int x = aud_get_int ("audgui", "playlist_manager_x"); int y = aud_get_int ("audgui", "playlist_manager_y"); @@ -268,13 +276,13 @@ EXPORT void audgui_playlist_manager (void) gtk_window_set_default_size ((GtkWindow *) playman_win, w, h); } - g_signal_connect ((GObject *) playman_win, "delete-event", (GCallback) - hide_cb, NULL); + g_signal_connect (playman_win, "delete-event", (GCallback) hide_cb, NULL); audgui_hide_on_escape (playman_win); - playman_vbox = gtk_vbox_new (FALSE, 6); - gtk_container_add( GTK_CONTAINER(playman_win) , playman_vbox ); + playman_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_container_add ((GtkContainer *) playman_win, playman_vbox); + /* ListView */ playman_pl_lv = audgui_list_new (& callbacks, NULL, aud_playlist_count ()); audgui_list_add_column (playman_pl_lv, _("Title"), 0, G_TYPE_STRING, -1); audgui_list_add_column (playman_pl_lv, _("Entries"), 1, G_TYPE_INT, 7); @@ -285,50 +293,45 @@ EXPORT void audgui_playlist_manager (void) hook_associate ("playlist activate", activate_hook, playman_pl_lv); hook_associate ("playlist set playing", position_hook, playman_pl_lv); - playman_pl_lv_sw = gtk_scrolled_window_new( NULL , NULL ); + playman_pl_lv_sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) playman_pl_lv_sw, GTK_SHADOW_IN); gtk_scrolled_window_set_policy ((GtkScrolledWindow *) playman_pl_lv_sw, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_container_add( GTK_CONTAINER(playman_pl_lv_sw) , playman_pl_lv ); + gtk_container_add ((GtkContainer *) playman_pl_lv_sw, playman_pl_lv); gtk_box_pack_start ((GtkBox *) playman_vbox, playman_pl_lv_sw, TRUE, TRUE, 0); - /* button bar */ - playman_bbar_hbbox = gtk_hbutton_box_new(); - gtk_button_box_set_layout( GTK_BUTTON_BOX(playman_bbar_hbbox) , GTK_BUTTONBOX_END ); - gtk_box_set_spacing ((GtkBox *) playman_bbar_hbbox, 6); - + /* ButtonBox */ + playman_button_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + new_button = gtk_button_new_from_stock (GTK_STOCK_NEW); + delete_button = gtk_button_new_from_stock (GTK_STOCK_DELETE); rename_button = gtk_button_new_with_mnemonic (_("_Rename")); gtk_button_set_image ((GtkButton *) rename_button, gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_BUTTON)); - new_button = gtk_button_new_from_stock (GTK_STOCK_NEW); - delete_button = gtk_button_new_from_stock (GTK_STOCK_DELETE); - - gtk_container_add ((GtkContainer *) playman_bbar_hbbox, rename_button); - gtk_button_box_set_child_secondary ((GtkButtonBox *) playman_bbar_hbbox, - rename_button, TRUE); - gtk_container_add ((GtkContainer *) playman_bbar_hbbox, new_button); - gtk_container_add ((GtkContainer *) playman_bbar_hbbox, delete_button); + play_button = gtk_button_new_from_stock (GTK_STOCK_MEDIA_PLAY); - gtk_box_pack_start( GTK_BOX(playman_vbox) , playman_bbar_hbbox , FALSE , FALSE , 0 ); + gtk_container_add ((GtkContainer *) playman_button_hbox, new_button); + gtk_container_add ((GtkContainer *) playman_button_hbox, delete_button); + gtk_box_pack_end ((GtkBox *) playman_button_hbox, play_button, FALSE, FALSE, 0); + gtk_box_pack_end ((GtkBox *) playman_button_hbox, rename_button, FALSE, FALSE, 0); + gtk_container_add ((GtkContainer *) playman_vbox, playman_button_hbox); - g_signal_connect ((GObject *) rename_button, "clicked", (GCallback) - rename_cb, playman_pl_lv); - g_signal_connect ((GObject *) new_button, "clicked", (GCallback) new_cb, - playman_pl_lv); - g_signal_connect ((GObject *) delete_button, "clicked", (GCallback) - delete_cb, playman_pl_lv); + g_signal_connect (new_button, "clicked", (GCallback) new_cb, NULL); + g_signal_connect (delete_button, "clicked", (GCallback) delete_cb, NULL); + g_signal_connect (rename_button, "clicked", (GCallback) rename_cb, NULL); + g_signal_connect (play_button, "clicked", (GCallback) play_cb, NULL); - hbox = gtk_hbox_new (FALSE, 6); + /* CheckButton */ + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start ((GtkBox *) playman_vbox, hbox, FALSE, FALSE, 0); - button = gtk_check_button_new_with_mnemonic + check_button = gtk_check_button_new_with_mnemonic (_("_Close dialog on activating playlist")); - gtk_box_pack_start ((GtkBox *) hbox, button, FALSE, FALSE, 0); - gtk_toggle_button_set_active ((GtkToggleButton *) button, aud_get_bool + gtk_box_pack_start ((GtkBox *) hbox, check_button, FALSE, FALSE, 0); + gtk_toggle_button_set_active ((GtkToggleButton *) check_button, aud_get_bool ("audgui", "playlist_manager_close_on_activate")); - g_signal_connect (button, "toggled", (GCallback) close_on_activate_cb, NULL); + g_signal_connect (check_button, "toggled", (GCallback) close_on_activate_cb, NULL); - gtk_widget_show_all( playman_win ); + gtk_widget_show_all (playman_win); hook_associate ("config save", save_config_cb, playman_win); } diff --git a/src/libaudgui/ui_regex.h b/src/libaudgui/ui_regex.h index aecf3fa..801a2ff 100644 --- a/src/libaudgui/ui_regex.h +++ b/src/libaudgui/ui_regex.h @@ -2,20 +2,19 @@ * ui_regex.h
* Copyright 2010 Carlo Bramini
*
- * 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
- * the Free Software Foundation; under version 3 of the License.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
*
- * This program 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses>.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
*
- * The Audacious team does not consider modular code linking to
- * Audacious or using our public API to be a derived work.
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
*/
#ifndef __UI_REGEX_H__
diff --git a/src/libaudgui/ui_urlopener.c b/src/libaudgui/ui_urlopener.c deleted file mode 100644 index daf0010..0000000 --- a/src/libaudgui/ui_urlopener.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * ui_urlopener.c - * Copyright 1998-2003 XMMS development team - * Copyright 2003-2004 BMP development team - * Copyright 2008-2011 Tomasz Moń and John Lindgren - * - * 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 - * the Free Software Foundation; under version 3 of the License. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses>. - * - * The Audacious team does not consider modular code linking to - * Audacious or using our public API to be a derived work. - */ - -#include <glib.h> -#include <gtk/gtk.h> - -#include <audacious/gtk-compat.h> -#include <audacious/i18n.h> -#include <audacious/drct.h> -#include <audacious/misc.h> - -#include "config.h" -#include "libaudgui.h" -#include "libaudgui-gtk.h" - -static void urlopener_add_url_callback (GtkWidget * widget, GtkEntry * entry) -{ - aud_history_add (gtk_entry_get_text (entry)); -} - -static GtkWidget * urlopener_add_url_dialog_new (GCallback func, bool_t open) -{ - GtkWidget * win, * vbox, * bbox, * cancel, * ok, * combo, * entry; - - win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title ((GtkWindow *) win, open ? _("Open URL") : _("Add URL")); - gtk_window_set_type_hint(GTK_WINDOW(win), GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER); - gtk_window_set_default_size(GTK_WINDOW(win), 400, -1); - gtk_container_set_border_width(GTK_CONTAINER(win), 12); - - vbox = gtk_vbox_new(FALSE, 10); - gtk_container_add(GTK_CONTAINER(win), vbox); - - combo = gtk_combo_box_text_new_with_entry (); - gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 0); - - entry = gtk_bin_get_child(GTK_BIN(combo)); - gtk_window_set_focus(GTK_WINDOW(win), entry); - gtk_entry_set_text(GTK_ENTRY(entry), ""); - - const char * path; - for (int i = 0; (path = aud_history_get (i)); i ++) - gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, path); - - g_signal_connect(entry, "activate", - G_CALLBACK(urlopener_add_url_callback), - entry); - g_signal_connect (entry, "activate", func, entry); - g_signal_connect_swapped(entry, "activate", - G_CALLBACK(gtk_widget_destroy), - win); - - bbox = gtk_hbutton_box_new(); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox), 5); - gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); - - cancel = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(bbox), cancel, FALSE, FALSE, 0); - gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(bbox), cancel, TRUE); - - g_signal_connect_swapped(cancel, "clicked", - G_CALLBACK(gtk_widget_destroy), - win); - - ok = gtk_button_new_from_stock (open ? GTK_STOCK_OPEN : GTK_STOCK_ADD); - g_signal_connect(ok, "clicked", - G_CALLBACK(urlopener_add_url_callback), entry); - g_signal_connect (ok, "clicked", func, entry); - g_signal_connect_swapped(ok, "clicked", - G_CALLBACK(gtk_widget_destroy), - win); - gtk_box_pack_start(GTK_BOX(bbox), ok, FALSE, FALSE, 0); - - gtk_widget_show_all(vbox); - - return win; -} - -static void -on_add_url_add_clicked(GtkWidget * widget, - GtkWidget * entry) -{ - const char *text = gtk_entry_get_text(GTK_ENTRY(entry)); - - if (text != NULL && * text) - aud_drct_pl_add (text, -1); -} - -static void -on_add_url_ok_clicked(GtkWidget * widget, - GtkWidget * entry) -{ - const char *text = gtk_entry_get_text(GTK_ENTRY(entry)); - - if (text != NULL && * text) - aud_drct_pl_open (text); -} - -EXPORT void audgui_show_add_url_window (bool_t open) -{ - static GtkWidget *url_window = NULL; - - if (!url_window) { - url_window = urlopener_add_url_dialog_new (open ? (GCallback) - on_add_url_ok_clicked : (GCallback) on_add_url_add_clicked, open); - - audgui_destroy_on_escape (url_window); - g_signal_connect(url_window, "destroy", - G_CALLBACK(gtk_widget_destroyed), - &url_window); - } - - gtk_window_present(GTK_WINDOW(url_window)); -} diff --git a/src/libaudgui/url-opener.c b/src/libaudgui/url-opener.c new file mode 100644 index 0000000..6e8512e --- /dev/null +++ b/src/libaudgui/url-opener.c @@ -0,0 +1,92 @@ +/* + * url-opener.c + * Copyright 2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#include <audacious/drct.h> +#include <audacious/i18n.h> +#include <audacious/misc.h> + +#include "config.h" +#include "init.h" +#include "libaudgui.h" + +static GtkWidget * window; + +static void response_cb (GtkWidget * dialog, int response) +{ + if (response == GTK_RESPONSE_ACCEPT) + { + GtkWidget * entry = g_object_get_data ((GObject *) dialog, "entry"); + const char * text = gtk_entry_get_text ((GtkEntry *) entry); + bool_t open = GPOINTER_TO_INT (g_object_get_data ((GObject *) dialog, "open")); + + if (open) + aud_drct_pl_open (text); + else + aud_drct_pl_add (text, -1); + + aud_history_add (text); + } + + gtk_widget_destroy (dialog); +} + +EXPORT void audgui_show_add_url_window (bool_t open) +{ + if (window) + gtk_widget_destroy (window); + + window = gtk_dialog_new_with_buttons (open ? _("Open URL") : _("Add URL"), + NULL, 0, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, open ? GTK_STOCK_OPEN : + GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT, NULL); + gtk_widget_set_size_request (window, 300, -1); + gtk_window_set_resizable ((GtkWindow *) window, FALSE); + gtk_dialog_set_default_response ((GtkDialog *) window, GTK_RESPONSE_ACCEPT); + + GtkWidget * box = gtk_dialog_get_content_area ((GtkDialog *) window); + + GtkWidget * label = gtk_label_new (_("Enter URL:")); + gtk_misc_set_alignment ((GtkMisc *) label, 0, 0); + gtk_box_pack_start ((GtkBox *) box, label, FALSE, FALSE, 0); + + GtkWidget * combo = gtk_combo_box_text_new_with_entry (); + gtk_box_pack_start ((GtkBox *) box, combo, FALSE, FALSE, 0); + + GtkWidget * entry = gtk_bin_get_child ((GtkBin *) combo); + gtk_entry_set_activates_default ((GtkEntry *) entry, TRUE); + + const char * item; + for (int i = 0; (item = aud_history_get (i)); i++) + gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, item); + + g_object_set_data ((GObject *) window, "entry", entry); + g_object_set_data ((GObject *) window, "open", GINT_TO_POINTER (open)); + + g_signal_connect (window, "response", (GCallback) response_cb, NULL); + g_signal_connect (window, "destroy", (GCallback) gtk_widget_destroyed, & window); + + gtk_widget_show_all (window); +} + +void audgui_url_opener_cleanup (void) +{ + if (window) + gtk_widget_destroy (window); +} diff --git a/src/libaudgui/util.c b/src/libaudgui/util.c index 49e9cee..3ca4073 100644 --- a/src/libaudgui/util.c +++ b/src/libaudgui/util.c @@ -1,6 +1,6 @@ /* * util.c - * Copyright 2010-2011 John Lindgren + * Copyright 2010-2012 John Lindgren * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,12 +17,13 @@ * the use of this software. */ +#include <string.h> + #include <gdk/gdkkeysyms.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include <gtk/gtk.h> #include <audacious/debug.h> -#include <audacious/gtk-compat.h> #include <audacious/i18n.h> #include <audacious/playlist.h> #include <audacious/misc.h> @@ -36,18 +37,56 @@ static GdkPixbuf * current_pixbuf; +EXPORT int audgui_get_digit_width (GtkWidget * widget) +{ + int width; + PangoLayout * layout = gtk_widget_create_pango_layout (widget, "0123456789"); + PangoFontDescription * desc = pango_font_description_new (); + pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD); + pango_layout_set_font_description (layout, desc); + pango_layout_get_pixel_size (layout, & width, NULL); + pango_font_description_free (desc); + return (width + 9) / 10; +} + +EXPORT void audgui_get_mouse_coords (GtkWidget * widget, int * x, int * y) +{ + if (widget) + { + int xwin, ywin; + GdkRectangle alloc; + + GdkWindow * window = gtk_widget_get_window (widget); + GdkDisplay * display = gdk_window_get_display (window); + GdkDeviceManager * manager = gdk_display_get_device_manager (display); + GdkDevice * device = gdk_device_manager_get_client_pointer (manager); + + gdk_window_get_device_position (window, device, & xwin, & ywin, NULL); + gtk_widget_get_allocation (widget, & alloc); + + * x = xwin - alloc.x; + * y = ywin - alloc.y; + } + else + { + GdkDisplay * display = gdk_display_get_default (); + GdkDeviceManager * manager = gdk_display_get_device_manager (display); + GdkDevice * device = gdk_device_manager_get_client_pointer (manager); + gdk_device_get_position (device, NULL, x, y); + } +} + EXPORT void audgui_hide_on_delete (GtkWidget * widget) { g_signal_connect (widget, "delete-event", (GCallback) gtk_widget_hide_on_delete, NULL); } -static bool_t escape_cb (GtkWidget * widget, GdkEventKey * event, void - (* action) (GtkWidget * widget)) +static bool_t escape_hide_cb (GtkWidget * widget, GdkEventKey * event) { - if (event->keyval == GDK_Escape) + if (event->keyval == GDK_KEY_Escape) { - action (widget); + gtk_widget_hide (widget); return TRUE; } @@ -56,14 +95,23 @@ static bool_t escape_cb (GtkWidget * widget, GdkEventKey * event, void EXPORT void audgui_hide_on_escape (GtkWidget * widget) { - g_signal_connect (widget, "key-press-event", (GCallback) escape_cb, - (void *) gtk_widget_hide); + g_signal_connect (widget, "key-press-event", (GCallback) escape_hide_cb, NULL); +} + +static bool_t escape_destroy_cb (GtkWidget * widget, GdkEventKey * event) +{ + if (event->keyval == GDK_KEY_Escape) + { + gtk_widget_destroy (widget); + return TRUE; + } + + return FALSE; } EXPORT void audgui_destroy_on_escape (GtkWidget * widget) { - g_signal_connect (widget, "key-press-event", (GCallback) escape_cb, - (void *) gtk_widget_destroy); + g_signal_connect (widget, "key-press-event", (GCallback) escape_destroy_cb, NULL); } static void toggle_cb (GtkToggleButton * toggle, bool_t * setting) @@ -205,7 +253,9 @@ EXPORT void audgui_pixbuf_scale_within (GdkPixbuf * * pixbuf, int size) { int width = gdk_pixbuf_get_width (* pixbuf); int height = gdk_pixbuf_get_height (* pixbuf); - GdkPixbuf * pixbuf2; + + if (width <= size && height <= size) + return; if (width > height) { @@ -223,7 +273,7 @@ EXPORT void audgui_pixbuf_scale_within (GdkPixbuf * * pixbuf, int size) if (height < 1) height = 1; - pixbuf2 = gdk_pixbuf_scale_simple (* pixbuf, width, height, + GdkPixbuf * pixbuf2 = gdk_pixbuf_scale_simple (* pixbuf, width, height, GDK_INTERP_BILINEAR); g_object_unref (* pixbuf); * pixbuf = pixbuf2; diff --git a/src/libaudtag/Makefile b/src/libaudtag/Makefile index cd2a8c7..98086d7 100644 --- a/src/libaudtag/Makefile +++ b/src/libaudtag/Makefile @@ -1,4 +1,4 @@ -LIB = ${LIB_PREFIX}audtag${LIB_SUFFIX} +SHARED_LIB = ${LIB_PREFIX}audtag${LIB_SUFFIX} LIB_MAJOR = 1 LIB_MINOR = 0 diff --git a/src/libaudtag/ape/ape.c b/src/libaudtag/ape/ape.c index 80ed420..d494403 100644 --- a/src/libaudtag/ape/ape.c +++ b/src/libaudtag/ape/ape.c @@ -1,21 +1,20 @@ /* + * ape.c * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ /* TODO: diff --git a/src/libaudtag/ape/ape.h b/src/libaudtag/ape/ape.h index 67f6830..0f22843 100644 --- a/src/libaudtag/ape/ape.h +++ b/src/libaudtag/ape/ape.h @@ -1,21 +1,20 @@ /* + * ape.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDTAG_APE_H diff --git a/src/libaudtag/audtag.c b/src/libaudtag/audtag.c index 705eeea..ecad6be 100644 --- a/src/libaudtag/audtag.c +++ b/src/libaudtag/audtag.c @@ -1,21 +1,20 @@ /* - * Copyright 2009 Paula Stanciu + * audtag.c + * Copyright 2009-2011 Paula Stanciu and John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/libaudtag/audtag.h b/src/libaudtag/audtag.h index dbb4e57..626e89d 100644 --- a/src/libaudtag/audtag.h +++ b/src/libaudtag/audtag.h @@ -1,25 +1,22 @@ /* - * Copyright 2009 Paula Stanciu + * audtag.h + * Copyright 2009-2011 Paula Stanciu and John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ -/* External Interface of the tagging library */ - #ifndef AUDTAG_H #define AUDTAG_H diff --git a/src/libaudtag/id3/id3-common.c b/src/libaudtag/id3/id3-common.c index dbad9be..aec6eb2 100644 --- a/src/libaudtag/id3/id3-common.c +++ b/src/libaudtag/id3/id3-common.c @@ -2,21 +2,19 @@ * id3-common.c * Copyright 2010-2011 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <stdio.h> diff --git a/src/libaudtag/id3/id3-common.h b/src/libaudtag/id3/id3-common.h index 9ad88a3..6a0c61e 100644 --- a/src/libaudtag/id3/id3-common.h +++ b/src/libaudtag/id3/id3-common.h @@ -2,21 +2,19 @@ * id3-common.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDTAG_ID3_COMMON_H diff --git a/src/libaudtag/id3/id3v1.c b/src/libaudtag/id3/id3v1.c index bc53f1f..7517d19 100644 --- a/src/libaudtag/id3/id3v1.c +++ b/src/libaudtag/id3/id3v1.c @@ -1,22 +1,20 @@ /* - * Copyright 2010 Tony Vroon - * Copyright 2011 Michał Lipski <tallica@o2.pl> + * id3v1.c + * Copyright 2010-2011 Tony Vroon, Michał Lipski, and John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/libaudtag/id3/id3v1.h b/src/libaudtag/id3/id3v1.h index 11f2356..623982d 100644 --- a/src/libaudtag/id3/id3v1.h +++ b/src/libaudtag/id3/id3v1.h @@ -1,21 +1,20 @@ /* + * id3v1.h * Copyright 2010 Tony Vroon * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef ID3V1_H diff --git a/src/libaudtag/id3/id3v22.c b/src/libaudtag/id3/id3v22.c index 909ad94..40cc345 100644 --- a/src/libaudtag/id3/id3v22.c +++ b/src/libaudtag/id3/id3v22.c @@ -1,24 +1,21 @@ /* - * Copyright 2009 Paula Stanciu - * Copyright 2010 John Lindgren - * Copyright 2010 Tony Vroon - * Copyright 2010 William Pitcock + * id3v24.c + * Copyright 2009-2011 Paula Stanciu, Tony Vroon, John Lindgren, + * and William Pitcock * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> @@ -69,7 +66,7 @@ ID3v2Header; typedef struct { - unsigned char key[3]; + char key[3]; unsigned char size[3]; } ID3v2FrameHeader; @@ -169,7 +166,7 @@ static bool_t read_frame (VFSFile * handle, int max_size, int version, TAGDBG (" size = %d\n", (int) hdrsz); * frame_size = sizeof (ID3v2FrameHeader) + hdrsz; - sprintf (key, "%.3s", header.key); + g_strlcpy (key, header.key, 4); * size = hdrsz; * data = g_malloc (* size); @@ -507,9 +504,6 @@ bool_t id3v22_read_tag (Tuple * tuple, VFSFile * handle) case ID3_COMMENT: decode_comment (tuple, data, size); break; - case ID3_ENCODER: - associate_string (tuple, -1, "encoder", data, size); - break; case ID3_TXX: decode_txx (tuple, data, size); break; diff --git a/src/libaudtag/id3/id3v22.h b/src/libaudtag/id3/id3v22.h index 2801d21..f78f8bb 100644 --- a/src/libaudtag/id3/id3v22.h +++ b/src/libaudtag/id3/id3v22.h @@ -1,21 +1,20 @@ /* + * id3v22.h * Copyright 2010 Tony Vroon * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDTAG_ID3V22_H diff --git a/src/libaudtag/id3/id3v24.c b/src/libaudtag/id3/id3v24.c index 5d492ca..d07e147 100644 --- a/src/libaudtag/id3/id3v24.c +++ b/src/libaudtag/id3/id3v24.c @@ -1,22 +1,21 @@ /* - * Copyright 2009 Paula Stanciu - * Copyright 2010 John Lindgren + * id3v24.c + * Copyright 2009-2011 Paula Stanciu, Tony Vroon, John Lindgren, + * Mikael Magnusson, and Michał Lipski * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> @@ -318,7 +317,7 @@ static bool_t read_frame (VFSFile * handle, int max_size, int version, TAGDBG (" flags = %x\n", (int) header.flags); * frame_size = sizeof (ID3v2FrameHeader) + header.size; - sprintf (key, "%.4s", header.key); + g_strlcpy (key, header.key, 5); if (header.flags & (ID3_FRAME_COMPRESSED | ID3_FRAME_ENCRYPTED)) { @@ -885,9 +884,6 @@ static bool_t id3v24_read_tag (Tuple * tuple, VFSFile * handle) case ID3_PRIVATE: decode_private_info (tuple, data, size); break; - case ID3_ENCODER: - associate_string (tuple, -1, "encoder", data, size); - break; case ID3_RVA2: decode_rva2 (tuple, data, size); break; diff --git a/src/libaudtag/id3/id3v24.h b/src/libaudtag/id3/id3v24.h index 1fdb3db..232c197 100644 --- a/src/libaudtag/id3/id3v24.h +++ b/src/libaudtag/id3/id3v24.h @@ -1,21 +1,20 @@ /* + * id3v24.h * Copyright 2010 John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 2 or version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef AUDTAG_ID3V2_H diff --git a/src/libaudtag/tag_module.c b/src/libaudtag/tag_module.c index 0ba7ec3..90f6806 100644 --- a/src/libaudtag/tag_module.c +++ b/src/libaudtag/tag_module.c @@ -1,21 +1,20 @@ /* - * Copyright 2009 Paula Stanciu + * tag_module.c + * Copyright 2009-2011 Paula Stanciu and John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/libaudtag/tag_module.h b/src/libaudtag/tag_module.h index dee3be2..a520c13 100644 --- a/src/libaudtag/tag_module.h +++ b/src/libaudtag/tag_module.h @@ -1,25 +1,22 @@ /* - * Copyright 2009 Paula Stanciu + * tag_module.h + * Copyright 2009-2011 Paula Stanciu, Tony Vroon, and John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ -/* Interface of the tagging library */ - #ifndef TAG_MODULE_H #define TAG_MODULE_H diff --git a/src/libaudtag/util.c b/src/libaudtag/util.c index 9fbf28a..9daee73 100644 --- a/src/libaudtag/util.c +++ b/src/libaudtag/util.c @@ -1,21 +1,20 @@ /* - * Copyright 2009 Paula Stanciu + * util.c + * Copyright 2009-2011 Paula Stanciu, Tony Vroon, and John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #include <glib.h> diff --git a/src/libaudtag/util.h b/src/libaudtag/util.h index c3808ad..e3284a0 100644 --- a/src/libaudtag/util.h +++ b/src/libaudtag/util.h @@ -1,21 +1,20 @@ /* - * Copyright 2009 Paula Stanciu + * util.h + * Copyright 2009-2010 Paula Stanciu and John Lindgren * - * This file is part of Audacious. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * - * Audacious 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, version 3 of the License. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. * - * Audacious 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. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. * - * You should have received a copy of the GNU General Public License along with - * Audacious. If not, see <http://www.gnu.org/licenses/>. - * - * The Audacious team does not consider modular code linking to Audacious or - * using our public API to be a derived work. + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. */ #ifndef TAGUTIL_H diff --git a/src/libeggsmclient/Makefile b/src/libeggsmclient/Makefile deleted file mode 100644 index bd5999b..0000000 --- a/src/libeggsmclient/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -STATIC_LIB_NOINST = libeggsmclient.a - -SRCS = eggdesktopfile.c eggsmclient.c eggsmclient-xsmp.c - -include ../../buildsys.mk -include ../../extra.mk - -CPPFLAGS += ${GLIB_CFLAGS} ${GTK_CFLAGS} ${SM_CFLAGS} -I../.. -DEGG_SM_CLIENT_BACKEND_XSMP -LIBS += ${GLIB_LIBS} ${GTK_LIBS} ${SM_LIBS} diff --git a/src/libeggsmclient/eggdesktopfile.c b/src/libeggsmclient/eggdesktopfile.c deleted file mode 100644 index 443d5ec..0000000 --- a/src/libeggsmclient/eggdesktopfile.c +++ /dev/null @@ -1,1528 +0,0 @@ -/* eggdesktopfile.c - Freedesktop.Org Desktop Files - * Copyright (C) 2007 Novell, Inc. - * - * Based on gnome-desktop-item.c - * Copyright (C) 1999, 2000 Red Hat Inc. - * Copyright (C) 2001 George Lebl - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - - * Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "eggdesktopfile.h" - -#include <string.h> -#include <unistd.h> - -#include <glib/gi18n.h> -#include <gdk/gdkx.h> -#include <gtk/gtk.h> - -struct EggDesktopFile { - GKeyFile *key_file; - char *source; - - char *name, *icon; - EggDesktopFileType type; - char document_code; -}; - -/** - * egg_desktop_file_new: - * @desktop_file_path: path to a Freedesktop-style Desktop file - * @error: error pointer - * - * Creates a new #EggDesktopFile for @desktop_file. - * - * Return value: the new #EggDesktopFile, or %NULL on error. - **/ -EggDesktopFile * -egg_desktop_file_new (const char *desktop_file_path, GError **error) -{ - GKeyFile *key_file; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_file (key_file, desktop_file_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } - - return egg_desktop_file_new_from_key_file (key_file, desktop_file_path, - error); -} - -/** - * egg_desktop_file_new_from_data_dirs: - * @desktop_file_path: relative path to a Freedesktop-style Desktop file - * @error: error pointer - * - * Looks for @desktop_file_path in the paths returned from - * g_get_user_data_dir() and g_get_system_data_dirs(), and creates - * a new #EggDesktopFile from it. - * - * Return value: the new #EggDesktopFile, or %NULL on error. - **/ -EggDesktopFile * -egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, - GError **error) -{ - EggDesktopFile *desktop_file; - GKeyFile *key_file; - char *full_path; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_data_dirs (key_file, desktop_file_path, - &full_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } - - desktop_file = egg_desktop_file_new_from_key_file (key_file, - full_path, - error); - g_free (full_path); - return desktop_file; -} - -/** - * egg_desktop_file_new_from_dirs: - * @desktop_file_path: relative path to a Freedesktop-style Desktop file - * @search_dirs: NULL-terminated array of directories to search - * @error: error pointer - * - * Looks for @desktop_file_path in the paths returned from - * g_get_user_data_dir() and g_get_system_data_dirs(), and creates - * a new #EggDesktopFile from it. - * - * Return value: the new #EggDesktopFile, or %NULL on error. - **/ -EggDesktopFile * -egg_desktop_file_new_from_dirs (const char *desktop_file_path, - const char **search_dirs, - GError **error) -{ - EggDesktopFile *desktop_file; - GKeyFile *key_file; - char *full_path; - - key_file = g_key_file_new (); - if (!g_key_file_load_from_dirs (key_file, desktop_file_path, search_dirs, - &full_path, 0, error)) - { - g_key_file_free (key_file); - return NULL; - } - - desktop_file = egg_desktop_file_new_from_key_file (key_file, - full_path, - error); - g_free (full_path); - return desktop_file; -} - -/** - * egg_desktop_file_new_from_key_file: - * @key_file: a #GKeyFile representing a desktop file - * @source: the path or URI that @key_file was loaded from, or %NULL - * @error: error pointer - * - * Creates a new #EggDesktopFile for @key_file. Assumes ownership of - * @key_file (on success or failure); you should consider @key_file to - * be freed after calling this function. - * - * Return value: the new #EggDesktopFile, or %NULL on error. - **/ -EggDesktopFile * -egg_desktop_file_new_from_key_file (GKeyFile *key_file, - const char *source, - GError **error) -{ - EggDesktopFile *desktop_file; - char *version, *type; - - if (!g_key_file_has_group (key_file, EGG_DESKTOP_FILE_GROUP)) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_INVALID, - _("File is not a valid .desktop file")); - g_key_file_free (key_file); - return NULL; - } - - version = g_key_file_get_value (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_VERSION, - NULL); - if (version) - { - double version_num; - char *end; - - version_num = g_ascii_strtod (version, &end); - if (*end) - { - g_warning ("Invalid Version string '%s' in %s", - version, source ? source : "(unknown)"); - } - else if (version_num > 1.0) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_INVALID, - /* translators: 'Version' is from a desktop file, and - * should not be translated. '%s' would probably be a - * version number. */ - _("Unrecognized desktop file Version '%s'"), version); - g_free (version); - g_key_file_free (key_file); - return NULL; - } - g_free (version); - } - - desktop_file = g_new0 (EggDesktopFile, 1); - desktop_file->key_file = key_file; - - if (g_path_is_absolute (source)) - desktop_file->source = g_filename_to_uri (source, NULL, NULL); - else - desktop_file->source = g_strdup (source); - - desktop_file->name = g_key_file_get_locale_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NAME, - NULL, - error); - if (!desktop_file->name) - { - egg_desktop_file_free (desktop_file); - return NULL; - } - - type = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TYPE, error); - if (!type) - { - egg_desktop_file_free (desktop_file); - return NULL; - } - - if (!strcmp (type, "Application")) - { - char *exec, *p; - - desktop_file->type = EGG_DESKTOP_FILE_TYPE_APPLICATION; - - exec = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - error); - if (!exec) - { - egg_desktop_file_free (desktop_file); - g_free (type); - return NULL; - } - - /* See if it takes paths or URIs or neither */ - for (p = exec; *p; p++) - { - if (*p == '%') - { - if (p[1] == '\0' || strchr ("FfUu", p[1])) - { - desktop_file->document_code = p[1]; - break; - } - p++; - } - } - - g_free (exec); - } - else if (!strcmp (type, "Link")) - { - char *url; - - desktop_file->type = EGG_DESKTOP_FILE_TYPE_LINK; - - url = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_URL, - error); - if (!url) - { - egg_desktop_file_free (desktop_file); - g_free (type); - return NULL; - } - g_free (url); - } - else if (!strcmp (type, "Directory")) - desktop_file->type = EGG_DESKTOP_FILE_TYPE_DIRECTORY; - else - desktop_file->type = EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED; - - g_free (type); - - /* Check the Icon key */ - desktop_file->icon = g_key_file_get_string (key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_ICON, - NULL); - if (desktop_file->icon && !g_path_is_absolute (desktop_file->icon)) - { - char *ext; - - /* Lots of .desktop files still get this wrong */ - ext = strrchr (desktop_file->icon, '.'); - if (ext && (!strcmp (ext, ".png") || - !strcmp (ext, ".xpm") || - !strcmp (ext, ".svg"))) - { - g_warning ("Desktop file '%s' has malformed Icon key '%s'" - "(should not include extension)", - source ? source : "(unknown)", - desktop_file->icon); - *ext = '\0'; - } - } - - return desktop_file; -} - -/** - * egg_desktop_file_free: - * @desktop_file: an #EggDesktopFile - * - * Frees @desktop_file. - **/ -void -egg_desktop_file_free (EggDesktopFile *desktop_file) -{ - g_key_file_free (desktop_file->key_file); - g_free (desktop_file->source); - g_free (desktop_file->name); - g_free (desktop_file->icon); - g_free (desktop_file); -} - -/** - * egg_desktop_file_get_source: - * @desktop_file: an #EggDesktopFile - * - * Gets the URI that @desktop_file was loaded from. - * - * Return value: @desktop_file's source URI - **/ -const char * -egg_desktop_file_get_source (EggDesktopFile *desktop_file) -{ - return desktop_file->source; -} - -/** - * egg_desktop_file_get_desktop_file_type: - * @desktop_file: an #EggDesktopFile - * - * Gets the desktop file type of @desktop_file. - * - * Return value: @desktop_file's type - **/ -EggDesktopFileType -egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file) -{ - return desktop_file->type; -} - -/** - * egg_desktop_file_get_name: - * @desktop_file: an #EggDesktopFile - * - * Gets the (localized) value of @desktop_file's "Name" key. - * - * Return value: the application/link name - **/ -const char * -egg_desktop_file_get_name (EggDesktopFile *desktop_file) -{ - return desktop_file->name; -} - -/** - * egg_desktop_file_get_icon: - * @desktop_file: an #EggDesktopFile - * - * Gets the value of @desktop_file's "Icon" key. - * - * If the icon string is a full path (that is, if g_path_is_absolute() - * returns %TRUE when called on it), it points to a file containing an - * unthemed icon. If the icon string is not a full path, it is the - * name of a themed icon, which can be looked up with %GtkIconTheme, - * or passed directly to a theme-aware widget like %GtkImage or - * %GtkCellRendererPixbuf. - * - * Return value: the icon path or name - **/ -const char * -egg_desktop_file_get_icon (EggDesktopFile *desktop_file) -{ - return desktop_file->icon; -} - -gboolean -egg_desktop_file_has_key (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -char * -egg_desktop_file_get_string (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -char * -egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - GError **error) -{ - return g_key_file_get_locale_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, locale, - error); -} - -gboolean -egg_desktop_file_get_boolean (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -double -egg_desktop_file_get_numeric (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_get_double (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -int -egg_desktop_file_get_integer (EggDesktopFile *desktop_file, - const char *key, - GError **error) -{ - return g_key_file_get_integer (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - error); -} - -char ** -egg_desktop_file_get_string_list (EggDesktopFile *desktop_file, - const char *key, - gsize *length, - GError **error) -{ - return g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, length, - error); -} - -char ** -egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - gsize *length, - GError **error) -{ - return g_key_file_get_locale_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, key, - locale, length, - error); -} - -/** - * egg_desktop_file_can_launch: - * @desktop_file: an #EggDesktopFile - * @desktop_environment: the name of the running desktop environment, - * or %NULL - * - * Tests if @desktop_file can/should be launched in the current - * environment. If @desktop_environment is non-%NULL, @desktop_file's - * "OnlyShowIn" and "NotShowIn" keys are checked to make sure that - * this desktop_file is appropriate for the named environment. - * - * Furthermore, if @desktop_file has type - * %EGG_DESKTOP_FILE_TYPE_APPLICATION, its "TryExec" key (if any) is - * also checked, to make sure the binary it points to exists. - * - * egg_desktop_file_can_launch() does NOT check the value of the - * "Hidden" key. - * - * Return value: %TRUE if @desktop_file can be launched - **/ -gboolean -egg_desktop_file_can_launch (EggDesktopFile *desktop_file, - const char *desktop_environment) -{ - char *try_exec, *found_program; - char **only_show_in, **not_show_in; - gboolean found; - int i; - - if (desktop_file->type != EGG_DESKTOP_FILE_TYPE_APPLICATION && - desktop_file->type != EGG_DESKTOP_FILE_TYPE_LINK) - return FALSE; - - if (desktop_environment) - { - only_show_in = g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN, - NULL, NULL); - if (only_show_in) - { - for (i = 0, found = FALSE; only_show_in[i] && !found; i++) - { - if (!strcmp (only_show_in[i], desktop_environment)) - found = TRUE; - } - - g_strfreev (only_show_in); - - if (!found) - return FALSE; - } - - not_show_in = g_key_file_get_string_list (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN, - NULL, NULL); - if (not_show_in) - { - for (i = 0, found = FALSE; not_show_in[i] && !found; i++) - { - if (!strcmp (not_show_in[i], desktop_environment)) - found = TRUE; - } - - g_strfreev (not_show_in); - - if (found) - return FALSE; - } - } - - if (desktop_file->type == EGG_DESKTOP_FILE_TYPE_APPLICATION) - { - try_exec = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TRY_EXEC, - NULL); - if (try_exec) - { - found_program = g_find_program_in_path (try_exec); - g_free (try_exec); - - if (!found_program) - return FALSE; - g_free (found_program); - } - } - - return TRUE; -} - -/** - * egg_desktop_file_accepts_documents: - * @desktop_file: an #EggDesktopFile - * - * Tests if @desktop_file represents an application that can accept - * documents on the command line. - * - * Return value: %TRUE or %FALSE - **/ -gboolean -egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file) -{ - return desktop_file->document_code != 0; -} - -/** - * egg_desktop_file_accepts_multiple: - * @desktop_file: an #EggDesktopFile - * - * Tests if @desktop_file can accept multiple documents at once. - * - * If this returns %FALSE, you can still pass multiple documents to - * egg_desktop_file_launch(), but that will result in multiple copies - * of the application being launched. See egg_desktop_file_launch() - * for more details. - * - * Return value: %TRUE or %FALSE - **/ -gboolean -egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file) -{ - return (desktop_file->document_code == 'F' || - desktop_file->document_code == 'U'); -} - -/** - * egg_desktop_file_accepts_uris: - * @desktop_file: an #EggDesktopFile - * - * Tests if @desktop_file can accept (non-"file:") URIs as documents to - * open. - * - * Return value: %TRUE or %FALSE - **/ -gboolean -egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file) -{ - return (desktop_file->document_code == 'U' || - desktop_file->document_code == 'u'); -} - -static void -append_quoted_word (GString *str, - const char *s, - gboolean in_single_quotes, - gboolean in_double_quotes) -{ - const char *p; - - if (!in_single_quotes && !in_double_quotes) - g_string_append_c (str, '\''); - else if (!in_single_quotes && in_double_quotes) - g_string_append (str, "\"'"); - - if (!strchr (s, '\'')) - g_string_append (str, s); - else - { - for (p = s; *p != '\0'; p++) - { - if (*p == '\'') - g_string_append (str, "'\\''"); - else - g_string_append_c (str, *p); - } - } - - if (!in_single_quotes && !in_double_quotes) - g_string_append_c (str, '\''); - else if (!in_single_quotes && in_double_quotes) - g_string_append (str, "'\""); -} - -static void -do_percent_subst (EggDesktopFile *desktop_file, - char code, - GString *str, - GSList **documents, - gboolean in_single_quotes, - gboolean in_double_quotes) -{ - GSList *d; - char *doc; - - switch (code) - { - case '%': - g_string_append_c (str, '%'); - break; - - case 'F': - case 'U': - for (d = *documents; d; d = d->next) - { - doc = d->data; - g_string_append (str, " "); - append_quoted_word (str, doc, in_single_quotes, in_double_quotes); - } - *documents = NULL; - break; - - case 'f': - case 'u': - if (*documents) - { - doc = (*documents)->data; - g_string_append (str, " "); - append_quoted_word (str, doc, in_single_quotes, in_double_quotes); - *documents = (*documents)->next; - } - break; - - case 'i': - if (desktop_file->icon) - { - g_string_append (str, "--icon "); - append_quoted_word (str, desktop_file->icon, - in_single_quotes, in_double_quotes); - } - break; - - case 'c': - if (desktop_file->name) - { - append_quoted_word (str, desktop_file->name, - in_single_quotes, in_double_quotes); - } - break; - - case 'k': - if (desktop_file->source) - { - append_quoted_word (str, desktop_file->source, - in_single_quotes, in_double_quotes); - } - break; - - case 'D': - case 'N': - case 'd': - case 'n': - case 'v': - case 'm': - /* Deprecated; skip */ - break; - - default: - g_warning ("Unrecognized %%-code '%%%c' in Exec", code); - break; - } -} - -static char * -parse_exec (EggDesktopFile *desktop_file, - GSList **documents, - GError **error) -{ - char *exec, *p, *command; - gboolean escape, single_quot, double_quot; - GString *gs; - - exec = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - error); - if (!exec) - return NULL; - - /* Build the command */ - gs = g_string_new (NULL); - escape = single_quot = double_quot = FALSE; - - for (p = exec; *p != '\0'; p++) - { - if (escape) - { - escape = FALSE; - g_string_append_c (gs, *p); - } - else if (*p == '\\') - { - if (!single_quot) - escape = TRUE; - g_string_append_c (gs, *p); - } - else if (*p == '\'') - { - g_string_append_c (gs, *p); - if (!single_quot && !double_quot) - single_quot = TRUE; - else if (single_quot) - single_quot = FALSE; - } - else if (*p == '"') - { - g_string_append_c (gs, *p); - if (!single_quot && !double_quot) - double_quot = TRUE; - else if (double_quot) - double_quot = FALSE; - } - else if (*p == '%' && p[1]) - { - do_percent_subst (desktop_file, p[1], gs, documents, - single_quot, double_quot); - p++; - } - else - g_string_append_c (gs, *p); - } - - g_free (exec); - command = g_string_free (gs, FALSE); - - /* Prepend "xdg-terminal " if needed (FIXME: use gvfs) */ - if (g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TERMINAL, - NULL)) - { - GError *terminal_error = NULL; - gboolean use_terminal = - g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TERMINAL, - &terminal_error); - if (terminal_error) - { - g_free (command); - g_propagate_error (error, terminal_error); - return NULL; - } - - if (use_terminal) - { - gs = g_string_new ("xdg-terminal "); - append_quoted_word (gs, command, FALSE, FALSE); - g_free (command); - command = g_string_free (gs, FALSE); - } - } - - return command; -} - -static GSList * -translate_document_list (EggDesktopFile *desktop_file, GSList *documents) -{ - gboolean accepts_uris = egg_desktop_file_accepts_uris (desktop_file); - GSList *ret, *d; - - for (d = documents, ret = NULL; d; d = d->next) - { - const char *document = d->data; - gboolean is_uri = !g_path_is_absolute (document); - char *translated; - - if (accepts_uris) - { - if (is_uri) - translated = g_strdup (document); - else - translated = g_filename_to_uri (document, NULL, NULL); - } - else - { - if (is_uri) - translated = g_filename_from_uri (document, NULL, NULL); - else - translated = g_strdup (document); - } - - if (translated) - ret = g_slist_prepend (ret, translated); - } - - return g_slist_reverse (ret); -} - -static void -free_document_list (GSList *documents) -{ - GSList *d; - - for (d = documents; d; d = d->next) - g_free (d->data); - g_slist_free (documents); -} - -/** - * egg_desktop_file_parse_exec: - * @desktop_file: a #EggDesktopFile - * @documents: a list of document paths or URIs - * @error: error pointer - * - * Parses @desktop_file's Exec key, inserting @documents into it, and - * returns the result. - * - * If @documents contains non-file: URIs and @desktop_file does not - * accept URIs, those URIs will be ignored. Likewise, if @documents - * contains more elements than @desktop_file accepts, the extra - * documents will be ignored. - * - * Return value: the parsed Exec string - **/ -char * -egg_desktop_file_parse_exec (EggDesktopFile *desktop_file, - GSList *documents, - GError **error) -{ - GSList *translated, *docs; - char *command; - - docs = translated = translate_document_list (desktop_file, documents); - command = parse_exec (desktop_file, &docs, error); - free_document_list (translated); - - return command; -} - -static gboolean -parse_link (EggDesktopFile *desktop_file, - EggDesktopFile **app_desktop_file, - GSList **documents, - GError **error) -{ - char *url; - GKeyFile *key_file; - - url = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_URL, - error); - if (!url) - return FALSE; - *documents = g_slist_prepend (NULL, url); - - /* FIXME: use gvfs */ - key_file = g_key_file_new (); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_NAME, - "xdg-open"); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_TYPE, - "Application"); - g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - "xdg-open %u"); - *app_desktop_file = egg_desktop_file_new_from_key_file (key_file, NULL, NULL); - return TRUE; -} - -#if GTK_CHECK_VERSION (2, 12, 0) -static char * -start_startup_notification (GdkDisplay *display, - EggDesktopFile *desktop_file, - const char *argv0, - int screen, - int workspace, - guint32 launch_time) -{ - static int sequence = 0; - char *startup_id; - char *description, *wmclass; - char *screen_str, *workspace_str; - - if (g_key_file_has_key (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, - NULL)) - { - if (!g_key_file_get_boolean (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, - NULL)) - return NULL; - wmclass = NULL; - } - else - { - wmclass = g_key_file_get_string (desktop_file->key_file, - EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS, - NULL); - if (!wmclass) - return NULL; - } - - if (launch_time == (guint32)-1) - launch_time = gdk_x11_display_get_user_time (display); - startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu", - g_get_prgname (), - (unsigned long)getpid (), - g_get_host_name (), - argv0, - sequence++, - (unsigned long)launch_time); - - description = g_strdup_printf (_("Starting %s"), desktop_file->name); - screen_str = g_strdup_printf ("%d", screen); - workspace_str = workspace == -1 ? NULL : g_strdup_printf ("%d", workspace); - - gdk_x11_display_broadcast_startup_message (display, "new", - "ID", startup_id, - "NAME", desktop_file->name, - "SCREEN", screen_str, - "BIN", argv0, - "ICON", desktop_file->icon, - "DESKTOP", workspace_str, - "DESCRIPTION", description, - "WMCLASS", wmclass, - NULL); - - g_free (description); - g_free (wmclass); - g_free (screen_str); - g_free (workspace_str); - - return startup_id; -} - -static void -end_startup_notification (GdkDisplay *display, - const char *startup_id) -{ - gdk_x11_display_broadcast_startup_message (display, "remove", - "ID", startup_id, - NULL); -} - -#define EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH (30 /* seconds */) - -typedef struct { - GdkDisplay *display; - char *startup_id; -} StartupNotificationData; - -static gboolean -startup_notification_timeout (gpointer data) -{ - StartupNotificationData *sn_data = data; - - end_startup_notification (sn_data->display, sn_data->startup_id); - g_object_unref (sn_data->display); - g_free (sn_data->startup_id); - g_free (sn_data); - - return FALSE; -} - -static void -set_startup_notification_timeout (GdkDisplay *display, - const char *startup_id) -{ - StartupNotificationData *sn_data; - - sn_data = g_new (StartupNotificationData, 1); - sn_data->display = g_object_ref (display); - sn_data->startup_id = g_strdup (startup_id); - - g_timeout_add_seconds (EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH, - startup_notification_timeout, sn_data); -} -#endif /* GTK 2.12 */ - -static GPtrArray * -array_putenv (GPtrArray *env, char *variable) -{ - guint i, keylen; - - if (!env) - { - char **envp; - - env = g_ptr_array_new (); - - envp = g_listenv (); - for (i = 0; envp[i]; i++) - { - const char *value; - - value = g_getenv (envp[i]); - g_ptr_array_add (env, g_strdup_printf ("%s=%s", envp[i], - value ? value : "")); - } - g_strfreev (envp); - } - - keylen = strcspn (variable, "="); - - /* Remove old value of key */ - for (i = 0; i < env->len; i++) - { - char *envvar = env->pdata[i]; - - if (!strncmp (envvar, variable, keylen) && envvar[keylen] == '=') - { - g_free (envvar); - g_ptr_array_remove_index_fast (env, i); - break; - } - } - - /* Add new value */ - g_ptr_array_add (env, g_strdup (variable)); - - return env; -} - -static gboolean -egg_desktop_file_launchv (EggDesktopFile *desktop_file, - GSList *documents, va_list args, - GError **error) -{ - EggDesktopFileLaunchOption option; - GSList *translated_documents = NULL, *docs = NULL; - char *command, **argv; - int argc, i, screen_num; - gboolean success, current_success; - GdkDisplay *display; - char *startup_id; - - GPtrArray *env = NULL; - char **variables = NULL; - GdkScreen *screen = NULL; - int workspace = -1; - const char *directory = NULL; - guint32 launch_time = (guint32)-1; - GSpawnFlags flags = G_SPAWN_SEARCH_PATH; - GSpawnChildSetupFunc setup_func = NULL; - gpointer setup_data = NULL; - - GPid *ret_pid = NULL; - int *ret_stdin = NULL, *ret_stdout = NULL, *ret_stderr = NULL; - char **ret_startup_id = NULL; - - if (documents && desktop_file->document_code == 0) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - _("Application does not accept documents on command line")); - return FALSE; - } - - /* Read the options: technically it's incorrect for the caller to - * NULL-terminate the list of options (rather than 0-terminating - * it), but NULL-terminating lets us use G_GNUC_NULL_TERMINATED, - * it's more consistent with other glib/gtk methods, and it will - * work as long as sizeof (int) <= sizeof (NULL), and NULL is - * represented as 0. (Which is true everywhere we care about.) - */ - while ((option = va_arg (args, EggDesktopFileLaunchOption))) - { - switch (option) - { - case EGG_DESKTOP_FILE_LAUNCH_CLEARENV: - if (env) - g_ptr_array_free (env, TRUE); - env = g_ptr_array_new (); - break; - case EGG_DESKTOP_FILE_LAUNCH_PUTENV: - variables = va_arg (args, char **); - for (i = 0; variables[i]; i++) - env = array_putenv (env, variables[i]); - break; - - case EGG_DESKTOP_FILE_LAUNCH_SCREEN: - screen = va_arg (args, GdkScreen *); - break; - case EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: - workspace = va_arg (args, int); - break; - - case EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: - directory = va_arg (args, const char *); - break; - case EGG_DESKTOP_FILE_LAUNCH_TIME: - launch_time = va_arg (args, guint32); - break; - case EGG_DESKTOP_FILE_LAUNCH_FLAGS: - flags |= va_arg (args, GSpawnFlags); - /* Make sure they didn't set any flags that don't make sense. */ - flags &= ~G_SPAWN_FILE_AND_ARGV_ZERO; - break; - case EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC: - setup_func = va_arg (args, GSpawnChildSetupFunc); - setup_data = va_arg (args, gpointer); - break; - - case EGG_DESKTOP_FILE_LAUNCH_RETURN_PID: - ret_pid = va_arg (args, GPid *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE: - ret_stdin = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE: - ret_stdout = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE: - ret_stderr = va_arg (args, int *); - break; - case EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID: - ret_startup_id = va_arg (args, char **); - break; - - default: - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION, - _("Unrecognized launch option: %d"), - GPOINTER_TO_INT (option)); - success = FALSE; - goto out; - } - } - - if (screen) - { - char *display_name = gdk_screen_make_display_name (screen); - char *display_env = g_strdup_printf ("DISPLAY=%s", display_name); - env = array_putenv (env, display_env); - g_free (display_name); - g_free (display_env); - - display = gdk_screen_get_display (screen); - } - else - { - display = gdk_display_get_default (); - screen = gdk_display_get_default_screen (display); - } - screen_num = gdk_screen_get_number (screen); - - translated_documents = translate_document_list (desktop_file, documents); - docs = translated_documents; - - success = FALSE; - - do - { - command = parse_exec (desktop_file, &docs, error); - if (!command) - goto out; - - if (!g_shell_parse_argv (command, &argc, &argv, error)) - { - g_free (command); - goto out; - } - g_free (command); - -#if GTK_CHECK_VERSION (2, 12, 0) - startup_id = start_startup_notification (display, desktop_file, - argv[0], screen_num, - workspace, launch_time); - if (startup_id) - { - char *startup_id_env = g_strdup_printf ("DESKTOP_STARTUP_ID=%s", - startup_id); - env = array_putenv (env, startup_id_env); - g_free (startup_id_env); - } -#else - startup_id = NULL; -#endif /* GTK 2.12 */ - - if (env != NULL) - g_ptr_array_add (env, NULL); - - current_success = - g_spawn_async_with_pipes (directory, - argv, - env ? (char **)(env->pdata) : NULL, - flags, - setup_func, setup_data, - ret_pid, - ret_stdin, ret_stdout, ret_stderr, - error); - g_strfreev (argv); - - if (startup_id) - { -#if GTK_CHECK_VERSION (2, 12, 0) - if (current_success) - { - set_startup_notification_timeout (display, startup_id); - - if (ret_startup_id) - *ret_startup_id = startup_id; - else - g_free (startup_id); - } - else -#endif /* GTK 2.12 */ - g_free (startup_id); - } - else if (ret_startup_id) - *ret_startup_id = NULL; - - if (current_success) - { - /* If we successfully launch any instances of the app, make - * sure we return TRUE and don't set @error. - */ - success = TRUE; - error = NULL; - - /* Also, only set the output params on the first one */ - ret_pid = NULL; - ret_stdin = ret_stdout = ret_stderr = NULL; - ret_startup_id = NULL; - } - } - while (docs && current_success); - - out: - if (env) - { - g_ptr_array_foreach (env, (GFunc)g_free, NULL); - g_ptr_array_free (env, TRUE); - } - free_document_list (translated_documents); - - return success; -} - -/** - * egg_desktop_file_launch: - * @desktop_file: an #EggDesktopFile - * @documents: a list of URIs or paths to documents to open - * @error: error pointer - * @...: additional options - * - * Launches @desktop_file with the given arguments. Additional options - * can be specified as follows: - * - * %EGG_DESKTOP_FILE_LAUNCH_CLEARENV: (no arguments) - * clears the environment in the child process - * %EGG_DESKTOP_FILE_LAUNCH_PUTENV: (char **variables) - * adds the NAME=VALUE strings in the given %NULL-terminated - * array to the child process's environment - * %EGG_DESKTOP_FILE_LAUNCH_SCREEN: (GdkScreen *screen) - * causes the application to be launched on the given screen - * %EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: (int workspace) - * causes the application to be launched on the given workspace - * %EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: (char *dir) - * causes the application to be launched in the given directory - * %EGG_DESKTOP_FILE_LAUNCH_TIME: (guint32 launch_time) - * sets the "launch time" for the application. If the user - * interacts with another window after @launch_time but before - * the launched application creates its first window, the window - * manager may choose to not give focus to the new application. - * Passing 0 for @launch_time will explicitly request that the - * application not receive focus. - * %EGG_DESKTOP_FILE_LAUNCH_FLAGS (GSpawnFlags flags) - * Sets additional #GSpawnFlags to use. See g_spawn_async() for - * more details. - * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC (GSpawnChildSetupFunc, gpointer) - * Sets the child setup callback and the data to pass to it. - * (See g_spawn_async() for more details.) - * - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID (GPid **pid) - * On a successful launch, sets *@pid to the PID of the launched - * application. - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID (char **startup_id) - * On a successful launch, sets *@startup_id to the Startup - * Notification "startup id" of the launched application. - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE (int *fd) - * On a successful launch, sets *@fd to the file descriptor of - * a pipe connected to the application's stdin. - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE (int *fd) - * On a successful launch, sets *@fd to the file descriptor of - * a pipe connected to the application's stdout. - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE (int *fd) - * On a successful launch, sets *@fd to the file descriptor of - * a pipe connected to the application's stderr. - * - * The options should be terminated with a single %NULL. - * - * If @documents contains multiple documents, but - * egg_desktop_file_accepts_multiple() returns %FALSE for - * @desktop_file, then egg_desktop_file_launch() will actually launch - * multiple instances of the application. In that case, the return - * value (as well as any values passed via - * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, etc) will only reflect the - * first instance of the application that was launched (but the - * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC will be called for each - * instance). - * - * Return value: %TRUE if the application was successfully launched. - **/ -gboolean -egg_desktop_file_launch (EggDesktopFile *desktop_file, - GSList *documents, GError **error, - ...) -{ - va_list args; - gboolean success; - EggDesktopFile *app_desktop_file; - - switch (desktop_file->type) - { - case EGG_DESKTOP_FILE_TYPE_APPLICATION: - va_start (args, error); - success = egg_desktop_file_launchv (desktop_file, documents, - args, error); - va_end (args); - break; - - case EGG_DESKTOP_FILE_TYPE_LINK: - if (documents) - { - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - /* translators: The 'Type=Link' string is found in a - * desktop file, and should not be translated. */ - _("Can't pass document URIs to a 'Type=Link' desktop entry")); - return FALSE; - } - - if (!parse_link (desktop_file, &app_desktop_file, &documents, error)) - return FALSE; - - va_start (args, error); - success = egg_desktop_file_launchv (app_desktop_file, documents, - args, error); - va_end (args); - - egg_desktop_file_free (app_desktop_file); - free_document_list (documents); - break; - - case EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED: - case EGG_DESKTOP_FILE_TYPE_DIRECTORY: - default: - g_set_error (error, EGG_DESKTOP_FILE_ERROR, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - _("Not a launchable item")); - success = FALSE; - break; - } - - return success; -} - - -GQuark -egg_desktop_file_error_quark (void) -{ - return g_quark_from_static_string ("egg-desktop_file-error-quark"); -} - - -G_LOCK_DEFINE_STATIC (egg_desktop_file); -static EggDesktopFile *egg_desktop_file; - -static void -egg_set_desktop_file_internal (const char *desktop_file_path, - gboolean set_defaults) -{ - GError *error = NULL; - - G_LOCK (egg_desktop_file); - if (egg_desktop_file) - egg_desktop_file_free (egg_desktop_file); - - egg_desktop_file = egg_desktop_file_new (desktop_file_path, &error); - if (error) - { - g_warning ("Could not load desktop file '%s': %s", - desktop_file_path, error->message); - g_error_free (error); - } - - if (set_defaults && egg_desktop_file != NULL) { - /* Set localized application name and default window icon */ - if (egg_desktop_file->name) - g_set_application_name (egg_desktop_file->name); - if (egg_desktop_file->icon) - { - if (g_path_is_absolute (egg_desktop_file->icon)) - gtk_window_set_default_icon_from_file (egg_desktop_file->icon, NULL); - else - gtk_window_set_default_icon_name (egg_desktop_file->icon); - } - } - - G_UNLOCK (egg_desktop_file); -} - -/** - * egg_set_desktop_file: - * @desktop_file_path: path to the application's desktop file - * - * Creates an #EggDesktopFile for the application from the data at - * @desktop_file_path. This will also call g_set_application_name() - * with the localized application name from the desktop file, and - * gtk_window_set_default_icon_name() or - * gtk_window_set_default_icon_from_file() with the application's - * icon. Other code may use additional information from the desktop - * file. - * See egg_set_desktop_file_without_defaults() for a variant of this - * function that does not set the application name and default window - * icon. - * - * Note that for thread safety reasons, this function can only - * be called once, and is mutually exclusive with calling - * egg_set_desktop_file_without_defaults(). - **/ -void -egg_set_desktop_file (const char *desktop_file_path) -{ - egg_set_desktop_file_internal (desktop_file_path, TRUE); -} - -/** - * egg_set_desktop_file_without_defaults: - * @desktop_file_path: path to the application's desktop file - * - * Creates an #EggDesktopFile for the application from the data at - * @desktop_file_path. - * See egg_set_desktop_file() for a variant of this function that - * sets the application name and default window icon from the information - * in the desktop file. - * - * Note that for thread safety reasons, this function can only - * be called once, and is mutually exclusive with calling - * egg_set_desktop_file(). - **/ -void -egg_set_desktop_file_without_defaults (const char *desktop_file_path) -{ - egg_set_desktop_file_internal (desktop_file_path, FALSE); -} - -/** - * egg_get_desktop_file: - * - * Gets the application's #EggDesktopFile, as set by - * egg_set_desktop_file(). - * - * Return value: the #EggDesktopFile, or %NULL if it hasn't been set. - **/ -EggDesktopFile * -egg_get_desktop_file (void) -{ - EggDesktopFile *retval; - - G_LOCK (egg_desktop_file); - retval = egg_desktop_file; - G_UNLOCK (egg_desktop_file); - - return retval; -} diff --git a/src/libeggsmclient/eggdesktopfile.h b/src/libeggsmclient/eggdesktopfile.h deleted file mode 100644 index 16c5426..0000000 --- a/src/libeggsmclient/eggdesktopfile.h +++ /dev/null @@ -1,163 +0,0 @@ -/* eggdesktopfile.h - Freedesktop.Org Desktop Files - * Copyright (C) 2007 Novell, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - - * Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __EGG_DESKTOP_FILE_H__ -#define __EGG_DESKTOP_FILE_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -typedef struct EggDesktopFile EggDesktopFile; - -typedef enum { - EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED, - - EGG_DESKTOP_FILE_TYPE_APPLICATION, - EGG_DESKTOP_FILE_TYPE_LINK, - EGG_DESKTOP_FILE_TYPE_DIRECTORY -} EggDesktopFileType; - -EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path, - GError **error); - -EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, - GError **error); -EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path, - const char **search_dirs, - GError **error); -EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file, - const char *source, - GError **error); - -void egg_desktop_file_free (EggDesktopFile *desktop_file); - -const char *egg_desktop_file_get_source (EggDesktopFile *desktop_file); - -EggDesktopFileType egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file); - -const char *egg_desktop_file_get_name (EggDesktopFile *desktop_file); -const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file); - -gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file, - const char *desktop_environment); - -gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file); -gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file); -gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file); - -char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file, - GSList *documents, - GError **error); - -gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file, - GSList *documents, - GError **error, - ...) G_GNUC_NULL_TERMINATED; - -typedef enum { - EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1, - EGG_DESKTOP_FILE_LAUNCH_PUTENV, - EGG_DESKTOP_FILE_LAUNCH_SCREEN, - EGG_DESKTOP_FILE_LAUNCH_WORKSPACE, - EGG_DESKTOP_FILE_LAUNCH_DIRECTORY, - EGG_DESKTOP_FILE_LAUNCH_TIME, - EGG_DESKTOP_FILE_LAUNCH_FLAGS, - EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC, - EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID -} EggDesktopFileLaunchOption; - -/* Standard Keys */ -#define EGG_DESKTOP_FILE_GROUP "Desktop Entry" - -#define EGG_DESKTOP_FILE_KEY_TYPE "Type" -#define EGG_DESKTOP_FILE_KEY_VERSION "Version" -#define EGG_DESKTOP_FILE_KEY_NAME "Name" -#define EGG_DESKTOP_FILE_KEY_GENERIC_NAME "GenericName" -#define EGG_DESKTOP_FILE_KEY_NO_DISPLAY "NoDisplay" -#define EGG_DESKTOP_FILE_KEY_COMMENT "Comment" -#define EGG_DESKTOP_FILE_KEY_ICON "Icon" -#define EGG_DESKTOP_FILE_KEY_HIDDEN "Hidden" -#define EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN "OnlyShowIn" -#define EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN "NotShowIn" -#define EGG_DESKTOP_FILE_KEY_TRY_EXEC "TryExec" -#define EGG_DESKTOP_FILE_KEY_EXEC "Exec" -#define EGG_DESKTOP_FILE_KEY_PATH "Path" -#define EGG_DESKTOP_FILE_KEY_TERMINAL "Terminal" -#define EGG_DESKTOP_FILE_KEY_MIME_TYPE "MimeType" -#define EGG_DESKTOP_FILE_KEY_CATEGORIES "Categories" -#define EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY "StartupNotify" -#define EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS "StartupWMClass" -#define EGG_DESKTOP_FILE_KEY_URL "URL" - -/* Accessors */ -gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file, - const char *key, - GError **error); -char *egg_desktop_file_get_string (EggDesktopFile *desktop_file, - const char *key, - GError **error) G_GNUC_MALLOC; -char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - GError **error) G_GNUC_MALLOC; -gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file, - const char *key, - GError **error); -double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file, - const char *key, - GError **error); -int egg_desktop_file_get_integer (EggDesktopFile *desktop_file, - const char *key, - GError **error); -char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file, - const char *key, - gsize *length, - GError **error) G_GNUC_MALLOC; -char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, - const char *key, - const char *locale, - gsize *length, - GError **error) G_GNUC_MALLOC; - - -/* Errors */ -#define EGG_DESKTOP_FILE_ERROR egg_desktop_file_error_quark() - -GQuark egg_desktop_file_error_quark (void); - -typedef enum { - EGG_DESKTOP_FILE_ERROR_INVALID, - EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, - EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION -} EggDesktopFileError; - -/* Global application desktop file */ -void egg_set_desktop_file (const char *desktop_file_path); -void egg_set_desktop_file_without_defaults (const char *desktop_file_path); -EggDesktopFile *egg_get_desktop_file (void); - - -G_END_DECLS - -#endif /* __EGG_DESKTOP_FILE_H__ */ diff --git a/src/libeggsmclient/eggsmclient-private.h b/src/libeggsmclient/eggsmclient-private.h deleted file mode 100644 index 0c98eee..0000000 --- a/src/libeggsmclient/eggsmclient-private.h +++ /dev/null @@ -1,59 +0,0 @@ -/* eggsmclient-private.h - * Copyright (C) 2007 Novell, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __EGG_SM_CLIENT_PRIVATE_H__ -#define __EGG_SM_CLIENT_PRIVATE_H__ - -#include <gtk/gtk.h> - -#if !GTK_CHECK_VERSION(2,91,7) && !GTK_CHECK_VERSION(3,0,0) -/* GTK+ 3 includes this automatically */ -#include <gdkconfig.h> -#endif - -#include "eggsmclient.h" - -G_BEGIN_DECLS - -GKeyFile *egg_sm_client_save_state (EggSMClient *client); -void egg_sm_client_quit_requested (EggSMClient *client); -void egg_sm_client_quit_cancelled (EggSMClient *client); -void egg_sm_client_quit (EggSMClient *client); - -#if defined (GDK_WINDOWING_X11) -# ifdef EGG_SM_CLIENT_BACKEND_XSMP -GType egg_sm_client_xsmp_get_type (void); -EggSMClient *egg_sm_client_xsmp_new (void); -# endif -# ifdef EGG_SM_CLIENT_BACKEND_DBUS -GType egg_sm_client_dbus_get_type (void); -EggSMClient *egg_sm_client_dbus_new (void); -# endif -#elif defined (GDK_WINDOWING_WIN32) -GType egg_sm_client_win32_get_type (void); -EggSMClient *egg_sm_client_win32_new (void); -#elif defined (GDK_WINDOWING_QUARTZ) -GType egg_sm_client_osx_get_type (void); -EggSMClient *egg_sm_client_osx_new (void); -#endif - -G_END_DECLS - - -#endif /* __EGG_SM_CLIENT_PRIVATE_H__ */ diff --git a/src/libeggsmclient/eggsmclient-xsmp.c b/src/libeggsmclient/eggsmclient-xsmp.c deleted file mode 100644 index d5cf3b5..0000000 --- a/src/libeggsmclient/eggsmclient-xsmp.c +++ /dev/null @@ -1,1380 +0,0 @@ -/* - * Copyright (C) 2007 Novell, Inc. - * - * Inspired by various other pieces of code including GsmClient (C) - * 2001 Havoc Pennington, GnomeClient (C) 1998 Carsten Schaar, and twm - * session code (C) 1998 The Open Group. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include "eggsmclient.h" -#include "eggsmclient-private.h" - -#include "eggdesktopfile.h" - -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <X11/SM/SMlib.h> - -#include <gdk/gdk.h> -#include <gdk/gdkx.h> - -#define EGG_TYPE_SM_CLIENT_XSMP (egg_sm_client_xsmp_get_type ()) -#define EGG_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMP)) -#define EGG_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)) -#define EGG_IS_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_XSMP)) -#define EGG_IS_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_XSMP)) -#define EGG_SM_CLIENT_XSMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)) - -typedef struct _EggSMClientXSMP EggSMClientXSMP; -typedef struct _EggSMClientXSMPClass EggSMClientXSMPClass; - -/* These mostly correspond to the similarly-named states in section - * 9.1 of the XSMP spec. Some of the states there aren't represented - * here, because we don't need them. SHUTDOWN_CANCELLED is slightly - * different from the spec; we use it when the client is IDLE after a - * ShutdownCancelled message, but the application is still interacting - * and doesn't know the shutdown has been cancelled yet. - */ -typedef enum -{ - XSMP_STATE_IDLE, - XSMP_STATE_SAVE_YOURSELF, - XSMP_STATE_INTERACT_REQUEST, - XSMP_STATE_INTERACT, - XSMP_STATE_SAVE_YOURSELF_DONE, - XSMP_STATE_SHUTDOWN_CANCELLED, - XSMP_STATE_CONNECTION_CLOSED -} EggSMClientXSMPState; - -static const char *state_names[] = { - "idle", - "save-yourself", - "interact-request", - "interact", - "save-yourself-done", - "shutdown-cancelled", - "connection-closed" -}; - -#define EGG_SM_CLIENT_XSMP_STATE(xsmp) (state_names[(xsmp)->state]) - -struct _EggSMClientXSMP -{ - EggSMClient parent; - - SmcConn connection; - char *client_id; - - EggSMClientXSMPState state; - char **restart_command; - gboolean set_restart_command; - int restart_style; - - guint idle; - - /* Current SaveYourself state */ - guint expecting_initial_save_yourself : 1; - guint need_save_state : 1; - guint need_quit_requested : 1; - guint interact_errors : 1; - guint shutting_down : 1; - - /* Todo list */ - guint waiting_to_set_initial_properties : 1; - guint waiting_to_emit_quit : 1; - guint waiting_to_emit_quit_cancelled : 1; - guint waiting_to_save_myself : 1; - -}; - -struct _EggSMClientXSMPClass -{ - EggSMClientClass parent_class; - -}; - -static void sm_client_xsmp_startup (EggSMClient *client, - const char *client_id); -static void sm_client_xsmp_set_restart_command (EggSMClient *client, - int argc, - const char **argv); -static void sm_client_xsmp_will_quit (EggSMClient *client, - gboolean will_quit); -static gboolean sm_client_xsmp_end_session (EggSMClient *client, - EggSMClientEndStyle style, - gboolean request_confirmation); - -static void xsmp_save_yourself (SmcConn smc_conn, - SmPointer client_data, - int save_style, - Bool shutdown, - int interact_style, - Bool fast); -static void xsmp_die (SmcConn smc_conn, - SmPointer client_data); -static void xsmp_save_complete (SmcConn smc_conn, - SmPointer client_data); -static void xsmp_shutdown_cancelled (SmcConn smc_conn, - SmPointer client_data); -static void xsmp_interact (SmcConn smc_conn, - SmPointer client_data); - -static SmProp *array_prop (const char *name, - ...); -static SmProp *ptrarray_prop (const char *name, - GPtrArray *values); -static SmProp *string_prop (const char *name, - const char *value); -static SmProp *card8_prop (const char *name, - unsigned char value); - -static void set_properties (EggSMClientXSMP *xsmp, ...); -static void delete_properties (EggSMClientXSMP *xsmp, ...); - -static GPtrArray *generate_command (char **restart_command, - const char *client_id, - const char *state_file); - -static void save_state (EggSMClientXSMP *xsmp); -static void do_save_yourself (EggSMClientXSMP *xsmp); -static void update_pending_events (EggSMClientXSMP *xsmp); - -static void ice_init (void); -static gboolean process_ice_messages (IceConn ice_conn); -static void smc_error_handler (SmcConn smc_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence, - int error_class, - int severity, - SmPointer values); - -G_DEFINE_TYPE (EggSMClientXSMP, egg_sm_client_xsmp, EGG_TYPE_SM_CLIENT) - -static void -egg_sm_client_xsmp_init (EggSMClientXSMP *xsmp) -{ - xsmp->state = XSMP_STATE_CONNECTION_CLOSED; - xsmp->connection = NULL; - xsmp->restart_style = SmRestartIfRunning; -} - -static void -egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass) -{ - EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass); - - sm_client_class->startup = sm_client_xsmp_startup; - sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command; - sm_client_class->will_quit = sm_client_xsmp_will_quit; - sm_client_class->end_session = sm_client_xsmp_end_session; -} - -EggSMClient * -egg_sm_client_xsmp_new (void) -{ -#if GTK_CHECK_VERSION(3,0,0) - if (!GDK_IS_X11_DISPLAY_MANAGER (gdk_display_manager_get ())) - return NULL; -#endif - - if (!g_getenv ("SESSION_MANAGER")) - return NULL; - - return g_object_new (EGG_TYPE_SM_CLIENT_XSMP, NULL); -} - -static gboolean -sm_client_xsmp_set_initial_properties (gpointer user_data) -{ - EggSMClientXSMP *xsmp = user_data; - EggDesktopFile *desktop_file; - GPtrArray *clone, *restart; - char pid_str[64]; - - if (xsmp->idle) - { - g_source_remove (xsmp->idle); - xsmp->idle = 0; - } - xsmp->waiting_to_set_initial_properties = FALSE; - - if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART) - xsmp->restart_style = SmRestartNever; - - /* Parse info out of desktop file */ - desktop_file = egg_get_desktop_file (); - if (desktop_file) - { - GError *err = NULL; - char *cmdline, **argv; - int argc; - - if (xsmp->restart_style == SmRestartIfRunning) - { - if (egg_desktop_file_get_boolean (desktop_file, - "X-GNOME-AutoRestart", NULL)) - xsmp->restart_style = SmRestartImmediately; - } - - if (!xsmp->set_restart_command) - { - cmdline = egg_desktop_file_parse_exec (desktop_file, NULL, &err); - if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err)) - { - egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp), - argc, (const char **)argv); - g_strfreev (argv); - } - else - { - g_warning ("Could not parse Exec line in desktop file: %s", - err->message); - g_error_free (err); - } - g_free (cmdline); - } - } - - if (!xsmp->set_restart_command) - xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1); - - clone = generate_command (xsmp->restart_command, NULL, NULL); - restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL); - - g_debug ("Setting initial properties"); - - /* Program, CloneCommand, RestartCommand, and UserID are required. - * ProcessID isn't required, but the SM may be able to do something - * useful with it. - */ - g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ()); - set_properties (xsmp, - string_prop (SmProgram, g_get_prgname ()), - ptrarray_prop (SmCloneCommand, clone), - ptrarray_prop (SmRestartCommand, restart), - string_prop (SmUserID, g_get_user_name ()), - string_prop (SmProcessID, pid_str), - card8_prop (SmRestartStyleHint, xsmp->restart_style), - NULL); - g_ptr_array_free (clone, TRUE); - g_ptr_array_free (restart, TRUE); - - if (desktop_file) - { - set_properties (xsmp, - string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)), - NULL); - } - - update_pending_events (xsmp); - return FALSE; -} - -/* This gets called from two different places: xsmp_die() (when the - * server asks us to disconnect) and process_ice_messages() (when the - * server disconnects unexpectedly). - */ -static void -sm_client_xsmp_disconnect (EggSMClientXSMP *xsmp) -{ - SmcConn connection; - - if (!xsmp->connection) - return; - - g_debug ("Disconnecting"); - - connection = xsmp->connection; - xsmp->connection = NULL; - SmcCloseConnection (connection, 0, NULL); - xsmp->state = XSMP_STATE_CONNECTION_CLOSED; - - xsmp->waiting_to_save_myself = FALSE; - update_pending_events (xsmp); -} - -static void -sm_client_xsmp_startup (EggSMClient *client, - const char *client_id) -{ - EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; - SmcCallbacks callbacks; - char *ret_client_id; - char error_string_ret[256]; - - xsmp->client_id = g_strdup (client_id); - - ice_init (); - SmcSetErrorHandler (smc_error_handler); - - callbacks.save_yourself.callback = xsmp_save_yourself; - callbacks.die.callback = xsmp_die; - callbacks.save_complete.callback = xsmp_save_complete; - callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled; - - callbacks.save_yourself.client_data = xsmp; - callbacks.die.client_data = xsmp; - callbacks.save_complete.client_data = xsmp; - callbacks.shutdown_cancelled.client_data = xsmp; - - client_id = NULL; - error_string_ret[0] = '\0'; - xsmp->connection = - SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor, - SmcSaveYourselfProcMask | SmcDieProcMask | - SmcSaveCompleteProcMask | - SmcShutdownCancelledProcMask, - &callbacks, - xsmp->client_id, &ret_client_id, - sizeof (error_string_ret), error_string_ret); - - if (!xsmp->connection) - { - g_warning ("Failed to connect to the session manager: %s\n", - error_string_ret[0] ? - error_string_ret : "no error message given"); - xsmp->state = XSMP_STATE_CONNECTION_CLOSED; - return; - } - - /* We expect a pointless initial SaveYourself if either (a) we - * didn't have an initial client ID, or (b) we DID have an initial - * client ID, but the server rejected it and gave us a new one. - */ - if (!xsmp->client_id || - (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0)) - xsmp->expecting_initial_save_yourself = TRUE; - - if (ret_client_id) - { - g_free (xsmp->client_id); - xsmp->client_id = g_strdup (ret_client_id); - free (ret_client_id); - - gdk_threads_enter (); -#if !GTK_CHECK_VERSION(2,23,3) && !GTK_CHECK_VERSION(3,0,0) - gdk_set_sm_client_id (xsmp->client_id); -#else - gdk_x11_set_sm_client_id (xsmp->client_id); -#endif - gdk_threads_leave (); - - g_debug ("Got client ID \"%s\"", xsmp->client_id); - } - - xsmp->state = XSMP_STATE_IDLE; - - /* Do not set the initial properties until we reach the main loop, - * so that the application has a chance to call - * egg_set_desktop_file(). (This may also help the session manager - * have a better idea of when the application is fully up and - * running.) - */ - xsmp->waiting_to_set_initial_properties = TRUE; - xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client); -} - -static void -sm_client_xsmp_set_restart_command (EggSMClient *client, - int argc, - const char **argv) -{ - EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; - int i; - - g_strfreev (xsmp->restart_command); - - xsmp->restart_command = g_new (char *, argc + 1); - for (i = 0; i < argc; i++) - xsmp->restart_command[i] = g_strdup (argv[i]); - xsmp->restart_command[i] = NULL; - - xsmp->set_restart_command = TRUE; -} - -static void -sm_client_xsmp_will_quit (EggSMClient *client, - gboolean will_quit) -{ - EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; - - if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED) - { - /* The session manager has already exited! Schedule a quit - * signal. - */ - xsmp->waiting_to_emit_quit = TRUE; - update_pending_events (xsmp); - return; - } - else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) - { - /* We received a ShutdownCancelled message while the application - * was interacting; Schedule a quit_cancelled signal. - */ - xsmp->waiting_to_emit_quit_cancelled = TRUE; - update_pending_events (xsmp); - return; - } - - g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT); - - g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True"); - SmcInteractDone (xsmp->connection, !will_quit); - - if (will_quit && xsmp->need_save_state) - save_state (xsmp); - - g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False"); - SmcSaveYourselfDone (xsmp->connection, will_quit); - xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; -} - -static gboolean -sm_client_xsmp_end_session (EggSMClient *client, - EggSMClientEndStyle style, - gboolean request_confirmation) -{ - EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; - int save_type; - - /* To end the session via XSMP, we have to send a - * SaveYourselfRequest. We aren't allowed to do that if anything - * else is going on, but we don't want to expose this fact to the - * application. So we do our best to patch things up here... - * - * In the worst case, this method might block for some length of - * time in process_ice_messages, but the only time that code path is - * honestly likely to get hit is if the application tries to end the - * session as the very first thing it does, in which case it - * probably won't actually block anyway. It's not worth gunking up - * the API to try to deal nicely with the other 0.01% of cases where - * this happens. - */ - - while (xsmp->state != XSMP_STATE_IDLE || - xsmp->expecting_initial_save_yourself) - { - /* If we're already shutting down, we don't need to do anything. */ - if (xsmp->shutting_down) - return TRUE; - - switch (xsmp->state) - { - case XSMP_STATE_CONNECTION_CLOSED: - return FALSE; - - case XSMP_STATE_SAVE_YOURSELF: - /* Trying to log out from the save_state callback? Whatever. - * Abort the save_state. - */ - SmcSaveYourselfDone (xsmp->connection, FALSE); - xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; - break; - - case XSMP_STATE_INTERACT_REQUEST: - case XSMP_STATE_INTERACT: - case XSMP_STATE_SHUTDOWN_CANCELLED: - /* Already in a shutdown-related state, just ignore - * the new shutdown request... - */ - return TRUE; - - case XSMP_STATE_IDLE: - if (xsmp->waiting_to_set_initial_properties) - sm_client_xsmp_set_initial_properties (xsmp); - - if (!xsmp->expecting_initial_save_yourself) - break; - /* else fall through */ - - case XSMP_STATE_SAVE_YOURSELF_DONE: - /* We need to wait for some response from the server.*/ - process_ice_messages (SmcGetIceConnection (xsmp->connection)); - break; - - default: - /* Hm... shouldn't happen */ - return FALSE; - } - } - - /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and - * the user chooses to save the session. But gnome-session will do - * the wrong thing if we pass SmSaveBoth and the user chooses NOT to - * save the session... Sigh. - */ - if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session")) - save_type = SmSaveBoth; - else - save_type = SmSaveGlobal; - - g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : ""); - SmcRequestSaveYourself (xsmp->connection, - save_type, - True, /* shutdown */ - SmInteractStyleAny, - !request_confirmation, /* fast */ - True /* global */); - return TRUE; -} - -static gboolean -idle_do_pending_events (gpointer data) -{ - EggSMClientXSMP *xsmp = data; - EggSMClient *client = data; - - gdk_threads_enter (); - - xsmp->idle = 0; - - if (xsmp->waiting_to_emit_quit) - { - xsmp->waiting_to_emit_quit = FALSE; - egg_sm_client_quit (client); - goto out; - } - - if (xsmp->waiting_to_emit_quit_cancelled) - { - xsmp->waiting_to_emit_quit_cancelled = FALSE; - egg_sm_client_quit_cancelled (client); - xsmp->state = XSMP_STATE_IDLE; - } - - if (xsmp->waiting_to_save_myself) - { - xsmp->waiting_to_save_myself = FALSE; - do_save_yourself (xsmp); - } - - out: - gdk_threads_leave (); - return FALSE; -} - -static void -update_pending_events (EggSMClientXSMP *xsmp) -{ - gboolean want_idle = - xsmp->waiting_to_emit_quit || - xsmp->waiting_to_emit_quit_cancelled || - xsmp->waiting_to_save_myself; - - if (want_idle) - { - if (xsmp->idle == 0) - xsmp->idle = g_idle_add (idle_do_pending_events, xsmp); - } - else - { - if (xsmp->idle != 0) - g_source_remove (xsmp->idle); - xsmp->idle = 0; - } -} - -static void -fix_broken_state (EggSMClientXSMP *xsmp, const char *message, - gboolean send_interact_done, - gboolean send_save_yourself_done) -{ - g_warning ("Received XSMP %s message in state %s: client or server error", - message, EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - /* Forget any pending SaveYourself plans we had */ - xsmp->waiting_to_save_myself = FALSE; - update_pending_events (xsmp); - - if (send_interact_done) - SmcInteractDone (xsmp->connection, False); - if (send_save_yourself_done) - SmcSaveYourselfDone (xsmp->connection, True); - - xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE; -} - -/* SM callbacks */ - -static void -xsmp_save_yourself (SmcConn smc_conn, - SmPointer client_data, - int save_type, - Bool shutdown, - int interact_style, - Bool fast) -{ - EggSMClientXSMP *xsmp = client_data; - gboolean wants_quit_requested; - - g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s", - save_type == SmSaveLocal ? "SmSaveLocal" : - save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth", - shutdown ? "Shutdown" : "!Shutdown", - interact_style == SmInteractStyleAny ? "SmInteractStyleAny" : - interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" : - "SmInteractStyleNone", fast ? "Fast" : "!Fast", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - if (xsmp->state != XSMP_STATE_IDLE && - xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED) - { - fix_broken_state (xsmp, "SaveYourself", FALSE, TRUE); - return; - } - - if (xsmp->waiting_to_set_initial_properties) - sm_client_xsmp_set_initial_properties (xsmp); - - /* If this is the initial SaveYourself, ignore it; we've already set - * properties and there's no reason to actually save state too. - */ - if (xsmp->expecting_initial_save_yourself) - { - xsmp->expecting_initial_save_yourself = FALSE; - - if (save_type == SmSaveLocal && - interact_style == SmInteractStyleNone && - !shutdown && !fast) - { - g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself"); - SmcSaveYourselfDone (xsmp->connection, True); - /* As explained in the comment at the end of - * do_save_yourself(), SAVE_YOURSELF_DONE is the correct - * state here, not IDLE. - */ - xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; - return; - } - else - g_warning ("First SaveYourself was not the expected one!"); - } - - /* Even ignoring the "fast" flag completely, there are still 18 - * different combinations of save_type, shutdown and interact_style. - * We interpret them as follows: - * - * Type Shutdown Interact Interpretation - * G F A/E/N do nothing (1) - * G T N do nothing (1)* - * G T A/E quit_requested (2) - * L/B F A/E/N save_state (3) - * L/B T N save_state (3)* - * L/B T A/E quit_requested, then save_state (4) - * - * 1. Do nothing, because the SM asked us to do something - * uninteresting (save open files, but then don't quit - * afterward) or rude (save open files without asking the user - * for confirmation). - * - * 2. Request interaction and then emit ::quit_requested. This - * perhaps isn't quite correct for the SmInteractStyleErrors - * case, but we don't care. - * - * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these - * rows essentially get demoted to SmSaveLocal, because their - * Global halves correspond to "do nothing". - * - * 4. Request interaction, emit ::quit_requested, and then emit - * ::save_state after interacting. This is the SmSaveBoth - * equivalent of #2, but we also promote SmSaveLocal shutdown - * SaveYourselfs to SmSaveBoth here, because we want to give - * the user a chance to save open files before quitting. - * - * (* It would be nice if we could do something useful when the - * session manager sends a SaveYourself with shutdown True and - * SmInteractStyleNone. But we can't, so we just pretend it didn't - * even tell us it was shutting down. The docs for ::quit mention - * that it might not always be preceded by ::quit_requested.) - */ - - /* As an optimization, we don't actually request interaction and - * emit ::quit_requested if the application isn't listening to the - * signal. - */ - wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT), 0, FALSE); - - xsmp->need_save_state = (save_type != SmSaveGlobal); - xsmp->need_quit_requested = (shutdown && wants_quit_requested && - interact_style != SmInteractStyleNone); - xsmp->interact_errors = (interact_style == SmInteractStyleErrors); - - xsmp->shutting_down = shutdown; - - do_save_yourself (xsmp); -} - -static void -do_save_yourself (EggSMClientXSMP *xsmp) -{ - if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) - { - /* The SM cancelled a previous SaveYourself, but we haven't yet - * had a chance to tell the application, so we can't start - * processing this SaveYourself yet. - */ - xsmp->waiting_to_save_myself = TRUE; - update_pending_events (xsmp); - return; - } - - if (xsmp->need_quit_requested) - { - xsmp->state = XSMP_STATE_INTERACT_REQUEST; - - g_debug ("Sending InteractRequest(%s)", - xsmp->interact_errors ? "Error" : "Normal"); - SmcInteractRequest (xsmp->connection, - xsmp->interact_errors ? SmDialogError : SmDialogNormal, - xsmp_interact, - xsmp); - return; - } - - if (xsmp->need_save_state) - { - save_state (xsmp); - - /* Though unlikely, the client could have been disconnected - * while the application was saving its state. - */ - if (!xsmp->connection) - return; - } - - g_debug ("Sending SaveYourselfDone(True)"); - SmcSaveYourselfDone (xsmp->connection, True); - - /* The client state diagram in the XSMP spec says that after a - * non-shutdown SaveYourself, we go directly back to "idle". But - * everything else in both the XSMP spec and the libSM docs - * disagrees. - */ - xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; -} - -static void -save_state (EggSMClientXSMP *xsmp) -{ - GKeyFile *state_file; - char *state_file_path, *data; - EggDesktopFile *desktop_file; - GPtrArray *restart; - int offset, fd; - - /* We set xsmp->state before emitting save_state, but our caller is - * responsible for setting it back afterward. - */ - xsmp->state = XSMP_STATE_SAVE_YOURSELF; - - state_file = egg_sm_client_save_state ((EggSMClient *)xsmp); - if (!state_file) - { - restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL); - set_properties (xsmp, - ptrarray_prop (SmRestartCommand, restart), - NULL); - g_ptr_array_free (restart, TRUE); - delete_properties (xsmp, SmDiscardCommand, NULL); - return; - } - - desktop_file = egg_get_desktop_file (); - if (desktop_file) - { - GKeyFile *merged_file; - char *desktop_file_path; - - merged_file = g_key_file_new (); - desktop_file_path = - g_filename_from_uri (egg_desktop_file_get_source (desktop_file), - NULL, NULL); - if (desktop_file_path && - g_key_file_load_from_file (merged_file, desktop_file_path, - G_KEY_FILE_KEEP_COMMENTS | - G_KEY_FILE_KEEP_TRANSLATIONS, NULL)) - { - guint g, k, i; - char **groups, **keys, *value, *exec; - - groups = g_key_file_get_groups (state_file, NULL); - for (g = 0; groups[g]; g++) - { - keys = g_key_file_get_keys (state_file, groups[g], NULL, NULL); - for (k = 0; keys[k]; k++) - { - value = g_key_file_get_value (state_file, groups[g], - keys[k], NULL); - if (value) - { - g_key_file_set_value (merged_file, groups[g], - keys[k], value); - g_free (value); - } - } - g_strfreev (keys); - } - g_strfreev (groups); - - g_key_file_free (state_file); - state_file = merged_file; - - /* Update Exec key using "--sm-client-state-file %k" */ - restart = generate_command (xsmp->restart_command, - NULL, "%k"); - for (i = 0; i < restart->len; i++) - restart->pdata[i] = g_shell_quote (restart->pdata[i]); - g_ptr_array_add (restart, NULL); - exec = g_strjoinv (" ", (char **)restart->pdata); - g_strfreev ((char **)restart->pdata); - g_ptr_array_free (restart, FALSE); - - g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP, - EGG_DESKTOP_FILE_KEY_EXEC, - exec); - g_free (exec); - } - else - desktop_file = NULL; - - g_free (desktop_file_path); - } - - /* Now write state_file to disk. (We can't use mktemp(), because - * that requires the filename to end with "XXXXXX", and we want - * it to end with ".desktop".) - */ - - data = g_key_file_to_data (state_file, NULL, NULL); - g_key_file_free (state_file); - - offset = 0; - while (1) - { - state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s", - g_get_user_config_dir (), - G_DIR_SEPARATOR, G_DIR_SEPARATOR, - g_get_prgname (), - (long)time (NULL) + offset, - desktop_file ? "desktop" : "state"); - - fd = open (state_file_path, O_WRONLY | O_CREAT | O_EXCL, 0644); - if (fd == -1) - { - if (errno == EEXIST) - { - offset++; - g_free (state_file_path); - continue; - } - else if (errno == ENOTDIR || errno == ENOENT) - { - char *sep = strrchr (state_file_path, G_DIR_SEPARATOR); - - *sep = '\0'; - if (g_mkdir_with_parents (state_file_path, 0755) != 0) - { - g_warning ("Could not create directory '%s'", - state_file_path); - g_free (state_file_path); - state_file_path = NULL; - break; - } - - continue; - } - - g_warning ("Could not create file '%s': %s", - state_file_path, g_strerror (errno)); - g_free (state_file_path); - state_file_path = NULL; - break; - } - - close (fd); - g_file_set_contents (state_file_path, data, -1, NULL); - break; - } - g_free (data); - - restart = generate_command (xsmp->restart_command, xsmp->client_id, - state_file_path); - set_properties (xsmp, - ptrarray_prop (SmRestartCommand, restart), - NULL); - g_ptr_array_free (restart, TRUE); - - if (state_file_path) - { - set_properties (xsmp, - array_prop (SmDiscardCommand, - "/bin/rm", "-rf", state_file_path, - NULL), - NULL); - g_free (state_file_path); - } -} - -static void -xsmp_interact (SmcConn smc_conn, - SmPointer client_data) -{ - EggSMClientXSMP *xsmp = client_data; - EggSMClient *client = client_data; - - g_debug ("Received Interact message in state %s", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - if (xsmp->state != XSMP_STATE_INTERACT_REQUEST) - { - fix_broken_state (xsmp, "Interact", TRUE, TRUE); - return; - } - - xsmp->state = XSMP_STATE_INTERACT; - egg_sm_client_quit_requested (client); -} - -static void -xsmp_die (SmcConn smc_conn, - SmPointer client_data) -{ - EggSMClientXSMP *xsmp = client_data; - EggSMClient *client = client_data; - - g_debug ("Received Die message in state %s", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - sm_client_xsmp_disconnect (xsmp); - egg_sm_client_quit (client); -} - -static void -xsmp_save_complete (SmcConn smc_conn, - SmPointer client_data) -{ - EggSMClientXSMP *xsmp = client_data; - - g_debug ("Received SaveComplete message in state %s", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE) - xsmp->state = XSMP_STATE_IDLE; - else - fix_broken_state (xsmp, "SaveComplete", FALSE, FALSE); -} - -static void -xsmp_shutdown_cancelled (SmcConn smc_conn, - SmPointer client_data) -{ - EggSMClientXSMP *xsmp = client_data; - EggSMClient *client = client_data; - - g_debug ("Received ShutdownCancelled message in state %s", - EGG_SM_CLIENT_XSMP_STATE (xsmp)); - - xsmp->shutting_down = FALSE; - - if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE) - { - /* We've finished interacting and now the SM has agreed to - * cancel the shutdown. - */ - xsmp->state = XSMP_STATE_IDLE; - egg_sm_client_quit_cancelled (client); - } - else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) - { - /* Hm... ok, so we got a shutdown SaveYourself, which got - * cancelled, but the application was still interacting, so we - * didn't tell it yet, and then *another* SaveYourself arrived, - * which we must still be waiting to tell the app about, except - * that now that SaveYourself has been cancelled too! Dizzy yet? - */ - xsmp->waiting_to_save_myself = FALSE; - update_pending_events (xsmp); - } - else - { - g_debug ("Sending SaveYourselfDone(False)"); - SmcSaveYourselfDone (xsmp->connection, False); - - if (xsmp->state == XSMP_STATE_INTERACT) - { - /* The application is currently interacting, so we can't - * tell it about the cancellation yet; we will wait until - * after it calls egg_sm_client_will_quit(). - */ - xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED; - } - else - { - /* The shutdown was cancelled before the application got a - * chance to interact. - */ - xsmp->state = XSMP_STATE_IDLE; - } - } -} - -/* Utilities */ - -/* Create a restart/clone/Exec command based on @restart_command. - * If @client_id is non-%NULL, add "--sm-client-id @client_id". - * If @state_file is non-%NULL, add "--sm-client-state-file @state_file". - * - * None of the input strings are g_strdup()ed; the caller must keep - * them around until it is done with the returned GPtrArray, and must - * then free the array, but not its contents. - */ -static GPtrArray * -generate_command (char **restart_command, const char *client_id, - const char *state_file) -{ - GPtrArray *cmd; - int i; - - cmd = g_ptr_array_new (); - g_ptr_array_add (cmd, restart_command[0]); - - if (client_id) - { - g_ptr_array_add (cmd, (char *)"--sm-client-id"); - g_ptr_array_add (cmd, (char *)client_id); - } - - if (state_file) - { - g_ptr_array_add (cmd, (char *)"--sm-client-state-file"); - g_ptr_array_add (cmd, (char *)state_file); - } - - for (i = 1; restart_command[i]; i++) - g_ptr_array_add (cmd, restart_command[i]); - - return cmd; -} - -/* Takes a NULL-terminated list of SmProp * values, created by - * array_prop, ptrarray_prop, string_prop, card8_prop, sets them, and - * frees them. - */ -static void -set_properties (EggSMClientXSMP *xsmp, ...) -{ - GPtrArray *props; - SmProp *prop; - va_list ap; - guint i; - - props = g_ptr_array_new (); - - va_start (ap, xsmp); - while ((prop = va_arg (ap, SmProp *))) - g_ptr_array_add (props, prop); - va_end (ap); - - if (xsmp->connection) - { - SmcSetProperties (xsmp->connection, props->len, - (SmProp **)props->pdata); - } - - for (i = 0; i < props->len; i++) - { - prop = props->pdata[i]; - g_free (prop->vals); - g_free (prop); - } - g_ptr_array_free (props, TRUE); -} - -/* Takes a NULL-terminated list of property names and deletes them. */ -static void -delete_properties (EggSMClientXSMP *xsmp, ...) -{ - GPtrArray *props; - char *prop; - va_list ap; - - if (!xsmp->connection) - return; - - props = g_ptr_array_new (); - - va_start (ap, xsmp); - while ((prop = va_arg (ap, char *))) - g_ptr_array_add (props, prop); - va_end (ap); - - SmcDeleteProperties (xsmp->connection, props->len, - (char **)props->pdata); - - g_ptr_array_free (props, TRUE); -} - -/* Takes an array of strings and creates a LISTofARRAY8 property. The - * strings are neither dupped nor freed; they need to remain valid - * until you're done with the SmProp. - */ -static SmProp * -array_prop (const char *name, ...) -{ - SmProp *prop; - SmPropValue pv; - GArray *vals; - char *value; - va_list ap; - - prop = g_new (SmProp, 1); - prop->name = (char *)name; - prop->type = (char *)SmLISTofARRAY8; - - vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue)); - - va_start (ap, name); - while ((value = va_arg (ap, char *))) - { - pv.length = strlen (value); - pv.value = value; - g_array_append_val (vals, pv); - } - - prop->num_vals = vals->len; - prop->vals = (SmPropValue *)vals->data; - - g_array_free (vals, FALSE); - - return prop; -} - -/* Takes a GPtrArray of strings and creates a LISTofARRAY8 property. - * The array contents are neither dupped nor freed; they need to - * remain valid until you're done with the SmProp. - */ -static SmProp * -ptrarray_prop (const char *name, GPtrArray *values) -{ - SmProp *prop; - SmPropValue pv; - GArray *vals; - guint i; - - prop = g_new (SmProp, 1); - prop->name = (char *)name; - prop->type = (char *)SmLISTofARRAY8; - - vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue)); - - for (i = 0; i < values->len; i++) - { - pv.length = strlen (values->pdata[i]); - pv.value = values->pdata[i]; - g_array_append_val (vals, pv); - } - - prop->num_vals = vals->len; - prop->vals = (SmPropValue *)vals->data; - - g_array_free (vals, FALSE); - - return prop; -} - -/* Takes a string and creates an ARRAY8 property. The string is - * neither dupped nor freed; it needs to remain valid until you're - * done with the SmProp. - */ -static SmProp * -string_prop (const char *name, const char *value) -{ - SmProp *prop; - - prop = g_new (SmProp, 1); - prop->name = (char *)name; - prop->type = (char *)SmARRAY8; - - prop->num_vals = 1; - prop->vals = g_new (SmPropValue, 1); - - prop->vals[0].length = strlen (value); - prop->vals[0].value = (char *)value; - - return prop; -} - -/* Takes a char and creates a CARD8 property. */ -static SmProp * -card8_prop (const char *name, unsigned char value) -{ - SmProp *prop; - char *card8val; - - /* To avoid having to allocate and free prop->vals[0], we cheat and - * make vals a 2-element-long array and then use the second element - * to store value. - */ - - prop = g_new (SmProp, 1); - prop->name = (char *)name; - prop->type = (char *)SmCARD8; - - prop->num_vals = 1; - prop->vals = g_new (SmPropValue, 2); - card8val = (char *)(&prop->vals[1]); - card8val[0] = value; - - prop->vals[0].length = 1; - prop->vals[0].value = card8val; - - return prop; -} - -/* ICE code. This makes no effort to play nice with anyone else trying - * to use libICE. Fortunately, no one uses libICE for anything other - * than SM. (DCOP uses ICE, but it has its own private copy of - * libICE.) - * - * When this moves to gtk, it will need to be cleverer, to avoid - * tripping over old apps that use GnomeClient or that use libSM - * directly. - */ - -#include <X11/ICE/ICElib.h> -#include <fcntl.h> - -static void ice_error_handler (IceConn ice_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence, - int error_class, - int severity, - IcePointer values); -static void ice_io_error_handler (IceConn ice_conn); -static void ice_connection_watch (IceConn ice_conn, - IcePointer client_data, - Bool opening, - IcePointer *watch_data); - -static void -ice_init (void) -{ - IceSetIOErrorHandler (ice_io_error_handler); - IceSetErrorHandler (ice_error_handler); - IceAddConnectionWatch (ice_connection_watch, NULL); -} - -static gboolean -process_ice_messages (IceConn ice_conn) -{ - IceProcessMessagesStatus status; - - gdk_threads_enter (); - status = IceProcessMessages (ice_conn, NULL, NULL); - gdk_threads_leave (); - - switch (status) - { - case IceProcessMessagesSuccess: - return TRUE; - - case IceProcessMessagesIOError: - sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn)); - return FALSE; - - case IceProcessMessagesConnectionClosed: - return FALSE; - - default: - g_assert_not_reached (); - } -} - -static gboolean -ice_iochannel_watch (GIOChannel *channel, - GIOCondition condition, - gpointer client_data) -{ - return process_ice_messages (client_data); -} - -static void -ice_connection_watch (IceConn ice_conn, - IcePointer client_data, - Bool opening, - IcePointer *watch_data) -{ - guint watch_id; - - if (opening) - { - GIOChannel *channel; - int fd = IceConnectionNumber (ice_conn); - - fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC); - channel = g_io_channel_unix_new (fd); - watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR, - ice_iochannel_watch, ice_conn); - g_io_channel_unref (channel); - - *watch_data = GUINT_TO_POINTER (watch_id); - } - else - { - watch_id = GPOINTER_TO_UINT (*watch_data); - g_source_remove (watch_id); - } -} - -static void -ice_error_handler (IceConn ice_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence, - int error_class, - int severity, - IcePointer values) -{ - /* Do nothing */ -} - -static void -ice_io_error_handler (IceConn ice_conn) -{ - /* Do nothing */ -} - -static void -smc_error_handler (SmcConn smc_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence, - int error_class, - int severity, - SmPointer values) -{ - /* Do nothing */ -} diff --git a/src/libeggsmclient/eggsmclient.c b/src/libeggsmclient/eggsmclient.c deleted file mode 100644 index 92be8a7..0000000 --- a/src/libeggsmclient/eggsmclient.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright (C) 2007 Novell, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; 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 <glib/gi18n.h> - -#include "eggsmclient.h" -#include "eggsmclient-private.h" - -static void egg_sm_client_debug_handler (const char *log_domain, - GLogLevelFlags log_level, - const char *message, - gpointer user_data); - -enum { - SAVE_STATE, - QUIT_REQUESTED, - QUIT_CANCELLED, - QUIT, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -struct _EggSMClientPrivate { - GKeyFile *state_file; -}; - -#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate)) - -G_DEFINE_TYPE (EggSMClient, egg_sm_client, G_TYPE_OBJECT) - -static EggSMClient *global_client; -static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL; - -static void -egg_sm_client_init (EggSMClient *client) -{ - ; -} - -static void -egg_sm_client_class_init (EggSMClientClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (EggSMClientPrivate)); - - /** - * EggSMClient::save_state: - * @client: the client - * @state_file: a #GKeyFile to save state information into - * - * Emitted when the session manager has requested that the - * application save information about its current state. The - * application should save its state into @state_file, and then the - * session manager may then restart the application in a future - * session and tell it to initialize itself from that state. - * - * You should not save any data into @state_file's "start group" - * (ie, the %NULL group). Instead, applications should save their - * data into groups with names that start with the application name, - * and libraries that connect to this signal should save their data - * into groups with names that start with the library name. - * - * Alternatively, rather than (or in addition to) using @state_file, - * the application can save its state by calling - * egg_sm_client_set_restart_command() during the processing of this - * signal (eg, to include a list of files to open). - **/ - signals[SAVE_STATE] = - g_signal_new ("save_state", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggSMClientClass, save_state), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, G_TYPE_POINTER); - - /** - * EggSMClient::quit_requested: - * @client: the client - * - * Emitted when the session manager requests that the application - * exit (generally because the user is logging out). The application - * should decide whether or not it is willing to quit (perhaps after - * asking the user what to do with documents that have unsaved - * changes) and then call egg_sm_client_will_quit(), passing %TRUE - * or %FALSE to give its answer to the session manager. (It does not - * need to give an answer before returning from the signal handler; - * it can interact with the user asynchronously and then give its - * answer later on.) If the application does not connect to this - * signal, then #EggSMClient will automatically return %TRUE on its - * behalf. - * - * The application should not save its session state as part of - * handling this signal; if the user has requested that the session - * be saved when logging out, then ::save_state will be emitted - * separately. - * - * If the application agrees to quit, it should then wait for either - * the ::quit_cancelled or ::quit signals to be emitted. - **/ - signals[QUIT_REQUESTED] = - g_signal_new ("quit_requested", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggSMClientClass, quit_requested), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - /** - * EggSMClient::quit_cancelled: - * @client: the client - * - * Emitted when the session manager decides to cancel a logout after - * the application has already agreed to quit. After receiving this - * signal, the application can go back to what it was doing before - * receiving the ::quit_requested signal. - **/ - signals[QUIT_CANCELLED] = - g_signal_new ("quit_cancelled", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - /** - * EggSMClient::quit: - * @client: the client - * - * Emitted when the session manager wants the application to quit - * (generally because the user is logging out). The application - * should exit as soon as possible after receiving this signal; if - * it does not, the session manager may choose to forcibly kill it. - * - * Normally a GUI application would only be sent a ::quit if it - * agreed to quit in response to a ::quit_requested signal. However, - * this is not guaranteed; in some situations the session manager - * may decide to end the session without giving applications a - * chance to object. - **/ - signals[QUIT] = - g_signal_new ("quit", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EggSMClientClass, quit), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} - -static gboolean sm_client_disable = FALSE; -static char *sm_client_state_file = NULL; -static char *sm_client_id = NULL; -static char *sm_config_prefix = NULL; - -static gboolean -sm_client_post_parse_func (GOptionContext *context, - GOptionGroup *group, - gpointer data, - GError **error) -{ - EggSMClient *client = egg_sm_client_get (); - - if (sm_client_id == NULL) - { - const gchar *desktop_autostart_id; - - desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID"); - - if (desktop_autostart_id != NULL) - sm_client_id = g_strdup (desktop_autostart_id); - } - - /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to - * use the same client id. */ - g_unsetenv ("DESKTOP_AUTOSTART_ID"); - - if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED && - EGG_SM_CLIENT_GET_CLASS (client)->startup) - EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id); - return TRUE; -} - -/** - * egg_sm_client_get_option_group: - * - * Creates a %GOptionGroup containing the session-management-related - * options. You should add this group to the application's - * %GOptionContext if you want to use #EggSMClient. - * - * Return value: the %GOptionGroup - **/ -GOptionGroup * -egg_sm_client_get_option_group (void) -{ - const GOptionEntry entries[] = { - { "sm-client-disable", 0, 0, - G_OPTION_ARG_NONE, &sm_client_disable, - N_("Disable connection to session manager"), NULL }, - { "sm-client-state-file", 0, 0, - G_OPTION_ARG_FILENAME, &sm_client_state_file, - N_("Specify file containing saved configuration"), N_("FILE") }, - { "sm-client-id", 0, 0, - G_OPTION_ARG_STRING, &sm_client_id, - N_("Specify session management ID"), N_("ID") }, - /* GnomeClient compatibility option */ - { "sm-disable", 0, G_OPTION_FLAG_HIDDEN, - G_OPTION_ARG_NONE, &sm_client_disable, - NULL, NULL }, - /* GnomeClient compatibility option. This is a dummy option that only - * exists so that sessions saved by apps with GnomeClient can be restored - * later when they've switched to EggSMClient. See bug #575308. - */ - { "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN, - G_OPTION_ARG_STRING, &sm_config_prefix, - NULL, NULL }, - { NULL } - }; - GOptionGroup *group; - - /* Use our own debug handler for the "EggSMClient" domain. */ - g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, - egg_sm_client_debug_handler, NULL); - - group = g_option_group_new ("sm-client", - _("Session management options:"), - _("Show session management options"), - NULL, NULL); - g_option_group_add_entries (group, entries); - g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func); - - return group; -} - -/** - * egg_sm_client_set_mode: - * @mode: an #EggSMClient mode - * - * Sets the "mode" of #EggSMClient as follows: - * - * %EGG_SM_CLIENT_MODE_DISABLED: Session management is completely - * disabled, until the mode is changed again. The application will - * not even connect to the session manager. (egg_sm_client_get() - * will still return an #EggSMClient object.) - * - * %EGG_SM_CLIENT_MODE_NO_RESTART: The application will connect to - * the session manager (and thus will receive notification when the - * user is logging out, etc), but will request to not be - * automatically restarted with saved state in future sessions. - * - * %EGG_SM_CLIENT_MODE_NORMAL: The default. #EggSMCLient will - * function normally. - * - * This must be called before the application's main loop begins and - * before any call to egg_sm_client_get(), unless the mode was set - * earlier to %EGG_SM_CLIENT_MODE_DISABLED and this call enables - * session management. Note that option parsing will call - * egg_sm_client_get(). - **/ -void -egg_sm_client_set_mode (EggSMClientMode mode) -{ - EggSMClientMode old_mode = global_client_mode; - - g_return_if_fail (global_client == NULL || global_client_mode == EGG_SM_CLIENT_MODE_DISABLED); - g_return_if_fail (!(global_client != NULL && mode == EGG_SM_CLIENT_MODE_DISABLED)); - - global_client_mode = mode; - - if (global_client != NULL && old_mode == EGG_SM_CLIENT_MODE_DISABLED) - { - if (EGG_SM_CLIENT_GET_CLASS (global_client)->startup) - EGG_SM_CLIENT_GET_CLASS (global_client)->startup (global_client, sm_client_id); - } -} - -/** - * egg_sm_client_get_mode: - * - * Gets the global #EggSMClientMode. See egg_sm_client_set_mode() - * for details. - * - * Return value: the global #EggSMClientMode - **/ -EggSMClientMode -egg_sm_client_get_mode (void) -{ - return global_client_mode; -} - -/** - * egg_sm_client_get: - * - * Returns the master #EggSMClient for the application. - * - * On platforms that support saved sessions (ie, POSIX/X11), the - * application will only request to be restarted by the session - * manager if you call egg_set_desktop_file() to set an application - * desktop file. In particular, if the desktop file contains the key - * "X - * - * Return value: the master #EggSMClient. - **/ -EggSMClient * -egg_sm_client_get (void) -{ - if (!global_client) - { - if (!sm_client_disable) - { -#if defined (GDK_WINDOWING_WIN32) - global_client = egg_sm_client_win32_new (); -#elif defined (GDK_WINDOWING_QUARTZ) - global_client = egg_sm_client_osx_new (); -#else - /* If both D-Bus and XSMP are compiled in, try XSMP first - * (since it supports state saving) and fall back to D-Bus - * if XSMP isn't available. - */ -# ifdef EGG_SM_CLIENT_BACKEND_XSMP - global_client = egg_sm_client_xsmp_new (); -# endif -# ifdef EGG_SM_CLIENT_BACKEND_DBUS - if (!global_client) - global_client = egg_sm_client_dbus_new (); -# endif -#endif - } - - /* Fallback: create a dummy client, so that callers don't have - * to worry about a %NULL return value. - */ - if (!global_client) - global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL); - } - - return global_client; -} - -/** - * egg_sm_client_is_resumed: - * @client: the client - * - * Checks whether or not the current session has been resumed from - * a previous saved session. If so, the application should call - * egg_sm_client_get_state_file() and restore its state from the - * returned #GKeyFile. - * - * Return value: %TRUE if the session has been resumed - **/ -gboolean -egg_sm_client_is_resumed (EggSMClient *client) -{ - g_return_val_if_fail (client == global_client, FALSE); - - return sm_client_state_file != NULL; -} - -/** - * egg_sm_client_get_state_file: - * @client: the client - * - * If the application was resumed by the session manager, this will - * return the #GKeyFile containing its state from the previous - * session. - * - * Note that other libraries and #EggSMClient itself may also store - * state in the key file, so if you call egg_sm_client_get_groups(), - * on it, the return value will likely include groups that you did not - * put there yourself. (It is also not guaranteed that the first - * group created by the application will still be the "start group" - * when it is resumed.) - * - * Return value: the #GKeyFile containing the application's earlier - * state, or %NULL on error. You should not free this key file; it - * is owned by @client. - **/ -GKeyFile * -egg_sm_client_get_state_file (EggSMClient *client) -{ - EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client); - char *state_file_path; - GError *err = NULL; - - g_return_val_if_fail (client == global_client, NULL); - - if (!sm_client_state_file) - return NULL; - if (priv->state_file) - return priv->state_file; - - if (!strncmp (sm_client_state_file, "file://", 7)) - state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL); - else - state_file_path = g_strdup (sm_client_state_file); - - priv->state_file = g_key_file_new (); - if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err)) - { - g_warning ("Could not load SM state file '%s': %s", - sm_client_state_file, err->message); - g_clear_error (&err); - g_key_file_free (priv->state_file); - priv->state_file = NULL; - } - - g_free (state_file_path); - return priv->state_file; -} - -/** - * egg_sm_client_set_restart_command: - * @client: the client - * @argc: the length of @argv - * @argv: argument vector - * - * Sets the command used to restart @client if it does not have a - * .desktop file that can be used to find its restart command. - * - * This can also be used when handling the ::save_state signal, to - * save the current state via an updated command line. (Eg, providing - * a list of filenames to open when the application is resumed.) - **/ -void -egg_sm_client_set_restart_command (EggSMClient *client, - int argc, - const char **argv) -{ - g_return_if_fail (EGG_IS_SM_CLIENT (client)); - - if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command) - EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv); -} - -/** - * egg_sm_client_will_quit: - * @client: the client - * @will_quit: whether or not the application is willing to quit - * - * This MUST be called in response to the ::quit_requested signal, to - * indicate whether or not the application is willing to quit. The - * application may call it either directly from the signal handler, or - * at some later point (eg, after asynchronously interacting with the - * user). - * - * If the application does not connect to ::quit_requested, - * #EggSMClient will call this method on its behalf (passing %TRUE - * for @will_quit). - * - * After calling this method, the application should wait to receive - * either ::quit_cancelled or ::quit. - **/ -void -egg_sm_client_will_quit (EggSMClient *client, - gboolean will_quit) -{ - g_return_if_fail (EGG_IS_SM_CLIENT (client)); - - if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit) - EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit); -} - -/** - * egg_sm_client_end_session: - * @style: a hint at how to end the session - * @request_confirmation: whether or not the user should get a chance - * to confirm the action - * - * Requests that the session manager end the current session. @style - * indicates how the session should be ended, and - * @request_confirmation indicates whether or not the user should be - * given a chance to confirm the logout/reboot/shutdown. Both of these - * flags are merely hints though; the session manager may choose to - * ignore them. - * - * Return value: %TRUE if the request was sent; %FALSE if it could not - * be (eg, because it could not connect to the session manager). - **/ -gboolean -egg_sm_client_end_session (EggSMClientEndStyle style, - gboolean request_confirmation) -{ - EggSMClient *client = egg_sm_client_get (); - - g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE); - - if (EGG_SM_CLIENT_GET_CLASS (client)->end_session) - { - return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style, - request_confirmation); - } - else - return FALSE; -} - -/* Signal-emitting callbacks from platform-specific code */ - -GKeyFile * -egg_sm_client_save_state (EggSMClient *client) -{ - GKeyFile *state_file; - char *group; - - g_return_val_if_fail (client == global_client, NULL); - - state_file = g_key_file_new (); - - g_debug ("Emitting save_state"); - g_signal_emit (client, signals[SAVE_STATE], 0, state_file); - g_debug ("Done emitting save_state"); - - group = g_key_file_get_start_group (state_file); - if (group) - { - g_free (group); - return state_file; - } - else - { - g_key_file_free (state_file); - return NULL; - } -} - -void -egg_sm_client_quit_requested (EggSMClient *client) -{ - g_return_if_fail (client == global_client); - - if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE)) - { - g_debug ("Not emitting quit_requested because no one is listening"); - egg_sm_client_will_quit (client, TRUE); - return; - } - - g_debug ("Emitting quit_requested"); - g_signal_emit (client, signals[QUIT_REQUESTED], 0); - g_debug ("Done emitting quit_requested"); -} - -void -egg_sm_client_quit_cancelled (EggSMClient *client) -{ - g_return_if_fail (client == global_client); - - g_debug ("Emitting quit_cancelled"); - g_signal_emit (client, signals[QUIT_CANCELLED], 0); - g_debug ("Done emitting quit_cancelled"); -} - -void -egg_sm_client_quit (EggSMClient *client) -{ - g_return_if_fail (client == global_client); - - g_debug ("Emitting quit"); - g_signal_emit (client, signals[QUIT], 0); - g_debug ("Done emitting quit"); - - /* FIXME: should we just call gtk_main_quit() here? */ -} - -static void -egg_sm_client_debug_handler (const char *log_domain, - GLogLevelFlags log_level, - const char *message, - gpointer user_data) -{ - static int debug = -1; - - if (debug < 0) - debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL); - - if (debug) - g_log_default_handler (log_domain, log_level, message, NULL); -} diff --git a/src/libeggsmclient/eggsmclient.h b/src/libeggsmclient/eggsmclient.h deleted file mode 100644 index e620b75..0000000 --- a/src/libeggsmclient/eggsmclient.h +++ /dev/null @@ -1,117 +0,0 @@ -/* eggsmclient.h - * Copyright (C) 2007 Novell, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __EGG_SM_CLIENT_H__ -#define __EGG_SM_CLIENT_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define EGG_TYPE_SM_CLIENT (egg_sm_client_get_type ()) -#define EGG_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT, EggSMClient)) -#define EGG_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT, EggSMClientClass)) -#define EGG_IS_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT)) -#define EGG_IS_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT)) -#define EGG_SM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT, EggSMClientClass)) - -typedef struct _EggSMClient EggSMClient; -typedef struct _EggSMClientClass EggSMClientClass; -typedef struct _EggSMClientPrivate EggSMClientPrivate; - -typedef enum { - EGG_SM_CLIENT_END_SESSION_DEFAULT, - EGG_SM_CLIENT_LOGOUT, - EGG_SM_CLIENT_REBOOT, - EGG_SM_CLIENT_SHUTDOWN -} EggSMClientEndStyle; - -typedef enum { - EGG_SM_CLIENT_MODE_DISABLED, - EGG_SM_CLIENT_MODE_NO_RESTART, - EGG_SM_CLIENT_MODE_NORMAL -} EggSMClientMode; - -struct _EggSMClient -{ - GObject parent; - -}; - -struct _EggSMClientClass -{ - GObjectClass parent_class; - - /* signals */ - void (*save_state) (EggSMClient *client, - GKeyFile *state_file); - - void (*quit_requested) (EggSMClient *client); - void (*quit_cancelled) (EggSMClient *client); - void (*quit) (EggSMClient *client); - - /* virtual methods */ - void (*startup) (EggSMClient *client, - const char *client_id); - void (*set_restart_command) (EggSMClient *client, - int argc, - const char **argv); - void (*will_quit) (EggSMClient *client, - gboolean will_quit); - gboolean (*end_session) (EggSMClient *client, - EggSMClientEndStyle style, - gboolean request_confirmation); - - /* Padding for future expansion */ - void (*_egg_reserved1) (void); - void (*_egg_reserved2) (void); - void (*_egg_reserved3) (void); - void (*_egg_reserved4) (void); -}; - -GType egg_sm_client_get_type (void) G_GNUC_CONST; - -GOptionGroup *egg_sm_client_get_option_group (void); - -/* Initialization */ -void egg_sm_client_set_mode (EggSMClientMode mode); -EggSMClientMode egg_sm_client_get_mode (void); -EggSMClient *egg_sm_client_get (void); - -/* Resuming a saved session */ -gboolean egg_sm_client_is_resumed (EggSMClient *client); -GKeyFile *egg_sm_client_get_state_file (EggSMClient *client); - -/* Alternate means of saving state */ -void egg_sm_client_set_restart_command (EggSMClient *client, - int argc, - const char **argv); - -/* Handling "quit_requested" signal */ -void egg_sm_client_will_quit (EggSMClient *client, - gboolean will_quit); - -/* Initiate a logout/reboot/shutdown */ -gboolean egg_sm_client_end_session (EggSMClientEndStyle style, - gboolean request_confirmation); - -G_END_DECLS - - -#endif /* __EGG_SM_CLIENT_H__ */ |