Mercurial > audlegacy-plugins
view src/null/null.c @ 866:d8b8b36d2709 trunk
[svn] - prevent skin list overlap when it's first populated and user quickly switchs to other tabs in the prefswin
author | giacomo |
---|---|
date | Fri, 16 Mar 2007 18:47:24 -0700 |
parents | d124034ebea3 |
children | e363a0fa8ea0 |
line wrap: on
line source
/* * Copyright 2006 Christian Birchinger <joker@netswarm.net> * * Based on the XMMS plugin: * Copyright 2000 Håvard Kvålen <havardk@sol.no> * * * 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; either version 2 of the License, or * (at your option) any later version. * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <glib.h> #include <audacious/i18n.h> #include <gtk/gtk.h> #include <audacious/plugin.h> #include <audacious/util.h> #include <audacious/configdb.h> #include "../../config.h" static GTimer *timer; static gulong offset_time, written; static gint bps; static gboolean real_time = TRUE; static gboolean paused, started; static GtkWidget *configurewin; static struct { AFormat format; gint frequency; gint channels; } input_format; #define ELAPSED_TIME (offset_time + g_timer_elapsed(timer, NULL) * 1000) static void null_init(void) { ConfigDb *db; db = bmp_cfg_db_open(); bmp_cfg_db_get_bool(db, "null", "real_time", &real_time); bmp_cfg_db_close(db); } static void null_about(void) { static GtkWidget *about; if (about) return; about = xmms_show_message(_("About Null Output"), _("Null output plugin " VERSION " by Christian Birchinger <joker@netswarm.net>\n" " based on the XMMS plugin by HÃ¥vard KvÃ¥l <havardk@xmms.org>"), _("Ok"), FALSE, NULL, NULL); g_signal_connect(G_OBJECT(about), "destroy", G_CALLBACK(gtk_widget_destroyed), &about); } static void null_configure_ok_cb(GtkButton *w, gpointer data) { ConfigDb *db; db = bmp_cfg_db_open(); real_time = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data)); bmp_cfg_db_set_bool(db, "null", "real_time", real_time); bmp_cfg_db_close(db); gtk_widget_destroy(configurewin); } static void null_configure(void) { GtkWidget *rt_btn, *ok_button, *cancel_button, *vbox, *bbox; if (configurewin) return; configurewin = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(configurewin), "Null output preferences"); gtk_window_set_policy(GTK_WINDOW(configurewin), FALSE, FALSE, FALSE); gtk_container_set_border_width(GTK_CONTAINER(configurewin), 10); gtk_signal_connect(GTK_OBJECT(configurewin), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &configurewin); vbox = gtk_vbox_new(FALSE, 10); gtk_container_add(GTK_CONTAINER(configurewin), vbox); rt_btn = gtk_check_button_new_with_label("Run in real time"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rt_btn), real_time); gtk_box_pack_start(GTK_BOX(vbox), rt_btn, FALSE, FALSE, 0); bbox = gtk_hbutton_box_new(); gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5); gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); ok_button = gtk_button_new_with_label("Ok"); cancel_button = gtk_button_new_with_label("Cancel"); GTK_WIDGET_SET_FLAGS(ok_button, GTK_CAN_DEFAULT); GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT); gtk_widget_grab_default(ok_button); gtk_signal_connect_object(GTK_OBJECT(cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(configurewin)); gtk_signal_connect(GTK_OBJECT(ok_button), "clicked", GTK_SIGNAL_FUNC(null_configure_ok_cb), rt_btn); gtk_box_pack_start_defaults(GTK_BOX(bbox), ok_button); gtk_box_pack_start_defaults(GTK_BOX(bbox), cancel_button); gtk_widget_show_all(configurewin); } static int null_open(AFormat fmt, int rate, int nch) { offset_time = 0; written = 0; started = FALSE; paused = FALSE; input_format.format = fmt; input_format.frequency = rate; input_format.channels = nch; bps = rate * nch; switch (fmt) { case FMT_U8: case FMT_S8: break; default: bps <<= 1; break; } if (real_time) timer = g_timer_new(); return 1; } static void null_write(void *ptr, int length) { EffectPlugin *ep; if (timer && !started) { g_timer_start(timer); started = TRUE; } if ((ep = get_current_effect_plugin()) != NULL && effects_enabled() && ep->mod_samples) ep->mod_samples(&ptr, length, input_format.format, input_format.frequency, input_format.channels); written += length; } static void null_close(void) { if (timer) g_timer_destroy(timer); timer = NULL; } static void null_flush(int time) { offset_time = time; written = ((double)time * bps) / 1000; if (timer) g_timer_reset(timer); } static void null_pause(short p) { paused = p; if (!timer) return; if (paused) g_timer_stop(timer); else { offset_time += g_timer_elapsed(timer, NULL) * 1000; g_timer_start(timer); } } static int null_buffer_free(void) { if (timer) { return 10240 - (written - (ELAPSED_TIME * bps) / 1000); } else { if (!paused) return 10000; else return 0; } } static int null_playing(void) { if (!timer) return FALSE; if ((gdouble)(written * 1000) / bps > ELAPSED_TIME) return TRUE; return FALSE; } static int null_get_written_time(void) { if (!bps) return 0; return ((gint64)written * 1000) / bps; } static int null_get_output_time(void) { if (!timer) return null_get_written_time(); return ELAPSED_TIME; } OutputPlugin null_op = { NULL, NULL, "Null output " VERSION, null_init, NULL, /* cleanup */ null_about, null_configure, NULL, /* Get volume */ NULL, /* Set volume */ null_open, null_write, null_close, null_flush, null_pause, null_buffer_free, null_playing, null_get_output_time, null_get_written_time, NULL /* tell */ }; OutputPlugin *get_oplugin_info(void) { return &null_op; }