Mercurial > audlegacy
view src/audacious/ui_main.c @ 3677:30ef1287da19
Seperate the 10hz loop dependent code from the rest of the remaining polling loop.
Also change the primary polling loop to 100hz (but really the rest can mostly be done with callbacks, or selectively).
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Mon, 01 Oct 2007 00:41:25 -0500 |
parents | 9e4edc01a0e3 |
children | e82ad057d1db |
line wrap: on
line source
/* Audacious - Cross-platform multimedia player * Copyright (C) 2005-2006 Audacious development team. * * BMP - Cross-platform multimedia player * 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. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <glib.h> #include <glib/gi18n.h> #include <glib/gprintf.h> #include <gtk/gtk.h> #include <gtk/gtkmessagedialog.h> /* GDK including */ #include "platform/smartinclude.h" #include <math.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #if defined(USE_REGEX_ONIGURUMA) #include <onigposix.h> #elif defined(USE_REGEX_PCRE) #include <pcreposix.h> #else #include <regex.h> #endif #include "ui_main.h" #include "icons-stock.h" #include "actions-mainwin.h" #include "main.h" #include "configdb.h" #include "dnd.h" #include "dock.h" #include "hints.h" #include "input.h" #include "playback.h" #include "playlist.h" #include "pluginenum.h" #include "ui_credits.h" #include "ui_equalizer.h" #include "ui_fileopener.h" #include "ui_manager.h" #include "ui_playlist.h" #include "ui_preferences.h" #include "ui_skinselector.h" #include "ui_urlopener.h" #include "strings.h" #include "util.h" #include "visualization.h" #include "skin.h" #include "ui_skinned_window.h" #include "ui_skinned_button.h" #include "ui_skinned_textbox.h" #include "ui_skinned_number.h" #include "ui_skinned_horizontal_slider.h" #include "ui_skinned_menurow.h" #include "ui_skinned_playstatus.h" #include "ui_skinned_monostereo.h" #include "ui_skinned_playlist.h" #include "ui_jumptotrack.h" #include "ui_main_evlisteners.h" static GTimeVal cb_time; /* click delay for tristate is defined by TRISTATE_THRESHOLD */ #define ITEM_SEPARATOR {"/-", NULL, NULL, 0, "<Separator>"} #define TRISTATE_THRESHOLD 200 #define VOLSET_DISP_TIMES 5 enum { MAINWIN_SEEK_REV = -1, MAINWIN_SEEK_NIL, MAINWIN_SEEK_FWD }; typedef struct _PlaybackInfo PlaybackInfo; struct _PlaybackInfo { gchar *title; gint bitrate; gint frequency; gint n_channels; }; GtkWidget *mainwin = NULL; GtkWidget *err = NULL; /* an error dialog for miscellaneous error messages */ static GdkBitmap *nullmask; static gint balance; static GtkWidget *mainwin_jtt = NULL; gint seek_state = MAINWIN_SEEK_NIL; gint seek_initial_pos = 0; static GtkWidget *mainwin_menubtn; static GtkWidget *mainwin_minimize, *mainwin_shade, *mainwin_close; static GtkWidget *mainwin_rew, *mainwin_fwd; static GtkWidget *mainwin_eject; static GtkWidget *mainwin_play, *mainwin_pause, *mainwin_stop; static GtkWidget *mainwin_shuffle, *mainwin_repeat; GtkWidget *mainwin_eq, *mainwin_pl; GtkWidget *mainwin_info; GtkWidget *mainwin_stime_min, *mainwin_stime_sec; static GtkWidget *mainwin_rate_text, *mainwin_freq_text, *mainwin_othertext; GtkWidget *mainwin_playstatus; GtkWidget *mainwin_minus_num, *mainwin_10min_num, *mainwin_min_num; GtkWidget *mainwin_10sec_num, *mainwin_sec_num; static gboolean setting_volume = FALSE; GtkWidget *mainwin_vis; GtkWidget *mainwin_svis; GtkWidget *mainwin_sposition = NULL; static GtkWidget *mainwin_menurow; static GtkWidget *mainwin_volume, *mainwin_balance; GtkWidget *mainwin_position; static GtkWidget *mainwin_monostereo; static GtkWidget *mainwin_srew, *mainwin_splay, *mainwin_spause; static GtkWidget *mainwin_sstop, *mainwin_sfwd, *mainwin_seject, *mainwin_about; static gint mainwin_timeout_id; static gboolean mainwin_info_text_locked = FALSE; static int ab_position_a = -1; static int ab_position_b = -1; static PlaybackInfo playback_info = { NULL, 0, 0, 0 }; static void mainwin_refresh_visible(void); static gint mainwin_idle_func(gpointer data); static void set_timer_mode_menu_cb(TimerMode mode); static void set_timer_mode(TimerMode mode); static void change_timer_mode(void); void mainwin_position_motion_cb(GtkWidget *widget, gint pos); void mainwin_position_release_cb(GtkWidget *widget, gint pos); void set_doublesize(gboolean doublesize); void mainwin_eq_pushed(gboolean toggled); void mainwin_pl_pushed(gboolean toggled); /* FIXME: placed here for now */ void playback_get_sample_params(gint * bitrate, gint * frequency, gint * n_channels) { if (bitrate) *bitrate = playback_info.bitrate; if (frequency) *frequency = playback_info.frequency; if (n_channels) *n_channels = playback_info.n_channels; } static void playback_set_sample_params(gint bitrate, gint frequency, gint n_channels) { if (bitrate >= 0) playback_info.bitrate = bitrate; if (frequency >= 0) playback_info.frequency = frequency; if (n_channels >= 0) playback_info.n_channels = n_channels; } static void mainwin_set_title_scroll(gboolean scroll) { cfg.autoscroll = scroll; ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll); } void mainwin_set_always_on_top(gboolean always) { GtkAction *action = gtk_action_group_get_action( toggleaction_group_others , "view always on top" ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , always ); } static void mainwin_set_shape_mask(void) { if (!cfg.player_visible) return; if (cfg.doublesize == FALSE) gtk_widget_shape_combine_mask(mainwin, skin_get_mask(bmp_active_skin, SKIN_MASK_MAIN), 0, 0); else gtk_widget_shape_combine_mask(mainwin, NULL, 0, 0); } static void mainwin_set_shade(gboolean shaded) { GtkAction *action = gtk_action_group_get_action( toggleaction_group_others , "roll up player" ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , shaded ); } static void mainwin_set_shade_menu_cb(gboolean shaded) { cfg.player_shaded = shaded; mainwin_set_shape_mask(); if (shaded) { dock_shade(dock_window_list, GTK_WINDOW(mainwin), MAINWIN_SHADED_HEIGHT * (cfg.doublesize + 1)); } else { gint height = !bmp_active_skin->properties.mainwin_height ? MAINWIN_HEIGHT : bmp_active_skin->properties.mainwin_height; dock_shade(dock_window_list, GTK_WINDOW(mainwin), height * (cfg.doublesize + 1)); } mainwin_refresh_visible(); ui_skinned_set_push_button_data(mainwin_shade, 0, cfg.player_shaded ? 27 : 18, 9, cfg.player_shaded ? 27 : 18); } static void mainwin_vis_set_refresh(RefreshRate rate) { cfg.vis_refresh = rate; } static void mainwin_vis_set_afalloff(FalloffSpeed speed) { cfg.analyzer_falloff = speed; } static void mainwin_vis_set_pfalloff(FalloffSpeed speed) { cfg.peaks_falloff = speed; } static void mainwin_vis_set_analyzer_mode(AnalyzerMode mode) { cfg.analyzer_mode = mode; } static void mainwin_vis_set_analyzer_type(AnalyzerType mode) { cfg.analyzer_type = mode; } void mainwin_vis_set_type(VisType mode) { GtkAction *action; switch ( mode ) { case VIS_ANALYZER: action = gtk_action_group_get_action( radioaction_group_vismode , "vismode analyzer" ); break; case VIS_SCOPE: action = gtk_action_group_get_action( radioaction_group_vismode , "vismode scope" ); break; case VIS_VOICEPRINT: action = gtk_action_group_get_action( radioaction_group_vismode , "vismode voiceprint" ); break; case VIS_OFF: default: action = gtk_action_group_get_action( radioaction_group_vismode , "vismode off" ); break; } gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , TRUE ); } static void mainwin_vis_set_type_menu_cb(VisType mode) { cfg.vis_type = mode; if (mode == VIS_OFF) { if (cfg.player_shaded) { ui_svis_set_visible(mainwin_svis, FALSE); ui_vis_set_visible(mainwin_vis, TRUE); } else { ui_svis_set_visible(mainwin_svis, TRUE); ui_vis_set_visible(mainwin_vis, FALSE); } } if (mode == VIS_ANALYZER || mode == VIS_SCOPE || mode == VIS_VOICEPRINT) { if (cfg.player_shaded) { ui_svis_clear_data(mainwin_svis); ui_svis_set_visible(mainwin_svis, TRUE); ui_vis_clear_data(mainwin_vis); ui_vis_set_visible(mainwin_vis, FALSE); } else { ui_svis_clear_data(mainwin_svis); ui_svis_set_visible(mainwin_svis, FALSE); ui_vis_clear_data(mainwin_vis); ui_vis_set_visible(mainwin_vis, TRUE); } } } static void mainwin_menubtn_cb(void) { gint x, y; gtk_window_get_position(GTK_WINDOW(mainwin), &x, &y); ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu), x + 6 * (1 + cfg.doublesize), y + MAINWIN_SHADED_HEIGHT * (1 + cfg.doublesize), 1, GDK_CURRENT_TIME); } void mainwin_minimize_cb(void) { if (!mainwin) return; gtk_window_iconify(GTK_WINDOW(mainwin)); } static void mainwin_shade_toggle(void) { mainwin_set_shade(!cfg.player_shaded); } void mainwin_quit_cb(void) { GList *playlists = NULL, *playlists_top = NULL; playlist_stop_get_info_thread(); gtk_widget_hide(equalizerwin); gtk_widget_hide(playlistwin); gtk_widget_hide(mainwin); g_source_remove(mainwin_timeout_id); bmp_config_save(); gtk_accel_map_save(bmp_paths[BMP_PATH_ACCEL_FILE]); plugin_system_cleanup(); /* free and clear each playlist */ playlists = playlist_get_playlists(); playlists_top = playlists; while ( playlists != NULL ) { playlist_clear((Playlist*)playlists->data); playlist_free((Playlist*)playlists->data); playlists = g_list_next(playlists); } g_list_free( playlists_top ); gtk_main_quit(); exit(EXIT_SUCCESS); } gboolean mainwin_vis_cb(GtkWidget *widget, GdkEventButton *event) { if (event->button == 1) { cfg.vis_type++; if (cfg.vis_type > VIS_OFF) cfg.vis_type = VIS_ANALYZER; mainwin_vis_set_type(cfg.vis_type); } else if (event->button == 3) { gint x, y; gdk_window_get_pointer(NULL, &x, &y, NULL); ui_manager_popup_menu_show(GTK_MENU(mainwin_visualization_menu), x, y, 3, event->time); } return TRUE; } static void mainwin_destroy(GtkWidget * widget, gpointer data) { mainwin_quit_cb(); } static gchar *mainwin_tb_old_text = NULL; void mainwin_lock_info_text(const gchar * text) { if (mainwin_info_text_locked != TRUE) mainwin_tb_old_text = g_strdup(bmp_active_skin->properties.mainwin_othertext_is_status ? UI_SKINNED_TEXTBOX(mainwin_othertext)->text : UI_SKINNED_TEXTBOX(mainwin_info)->text); mainwin_info_text_locked = TRUE; if (bmp_active_skin->properties.mainwin_othertext_is_status) ui_skinned_textbox_set_text(mainwin_othertext, text); else ui_skinned_textbox_set_text(mainwin_info, text); } void mainwin_release_info_text(void) { mainwin_info_text_locked = FALSE; if (mainwin_tb_old_text != NULL) { if (bmp_active_skin->properties.mainwin_othertext_is_status) ui_skinned_textbox_set_text(mainwin_othertext, mainwin_tb_old_text); else ui_skinned_textbox_set_text(mainwin_info, mainwin_tb_old_text); g_free(mainwin_tb_old_text); mainwin_tb_old_text = NULL; } } static gchar * make_mainwin_title(const gchar * title) { if (title) return g_strdup_printf(_("%s - Audacious"), title); else return g_strdup(_("Audacious")); } void mainwin_set_song_title(const gchar * title) { gchar *mainwin_title_text = make_mainwin_title(title); gtk_window_set_title(GTK_WINDOW(mainwin), mainwin_title_text); } static void mainwin_refresh_visible(void) { if (!bmp_active_skin || !cfg.player_visible) return; gtk_widget_show_all(mainwin); if (!bmp_active_skin->properties.mainwin_text_visible) gtk_widget_hide(mainwin_info); if (!bmp_active_skin->properties.mainwin_vis_visible) gtk_widget_hide(mainwin_vis); if (!bmp_active_skin->properties.mainwin_menurow_visible) gtk_widget_hide(mainwin_menurow); if (bmp_active_skin->properties.mainwin_othertext) { gtk_widget_hide(mainwin_rate_text); gtk_widget_hide(mainwin_freq_text); gtk_widget_hide(mainwin_monostereo); if (!bmp_active_skin->properties.mainwin_othertext_visible) gtk_widget_hide(mainwin_othertext); } else { gtk_widget_hide(mainwin_othertext); } if (!bmp_active_skin->properties.mainwin_vis_visible) gtk_widget_hide(mainwin_vis); if (!playback_get_playing()) { gtk_widget_hide(mainwin_minus_num); gtk_widget_hide(mainwin_10min_num); gtk_widget_hide(mainwin_min_num); gtk_widget_hide(mainwin_10sec_num); gtk_widget_hide(mainwin_sec_num); gtk_widget_hide(mainwin_stime_min); gtk_widget_hide(mainwin_stime_sec); gtk_widget_hide(mainwin_position); gtk_widget_hide(mainwin_sposition); } if (cfg.player_shaded) { ui_svis_clear_data(mainwin_svis); if (cfg.vis_type != VIS_OFF) ui_svis_set_visible(mainwin_svis, TRUE); else ui_svis_set_visible(mainwin_svis, FALSE); ui_skinned_textbox_set_scroll(mainwin_info, FALSE); if (!playback_get_playing()) { gtk_widget_hide(mainwin_sposition); gtk_widget_hide(mainwin_stime_min); gtk_widget_hide(mainwin_stime_sec); } } else { gtk_widget_hide(mainwin_srew); gtk_widget_hide(mainwin_splay); gtk_widget_hide(mainwin_spause); gtk_widget_hide(mainwin_sstop); gtk_widget_hide(mainwin_sfwd); gtk_widget_hide(mainwin_seject); gtk_widget_hide(mainwin_stime_min); gtk_widget_hide(mainwin_stime_sec); gtk_widget_hide(mainwin_svis); gtk_widget_hide(mainwin_sposition); ui_vis_clear_data(mainwin_vis); if (cfg.vis_type != VIS_OFF) ui_vis_set_visible(mainwin_vis, TRUE); else ui_vis_set_visible(mainwin_vis, FALSE); ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll); } } void mainwin_refresh_hints(void) { /* positioning and size attributes */ if (bmp_active_skin->properties.mainwin_vis_x && bmp_active_skin->properties.mainwin_vis_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_vis), bmp_active_skin->properties.mainwin_vis_x, bmp_active_skin->properties.mainwin_vis_y); if (bmp_active_skin->properties.mainwin_vis_width) gtk_widget_set_size_request(mainwin_vis, bmp_active_skin->properties.mainwin_vis_width*(1+cfg.doublesize), UI_VIS(mainwin_vis)->height*(1+cfg.doublesize)); if (bmp_active_skin->properties.mainwin_text_x && bmp_active_skin->properties.mainwin_text_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_info), bmp_active_skin->properties.mainwin_text_x, bmp_active_skin->properties.mainwin_text_y); if (bmp_active_skin->properties.mainwin_text_width) gtk_widget_set_size_request(mainwin_info, bmp_active_skin->properties.mainwin_text_width*(1+cfg.doublesize), UI_SKINNED_TEXTBOX(mainwin_info)->height*(1+cfg.doublesize)); if (bmp_active_skin->properties.mainwin_infobar_x && bmp_active_skin->properties.mainwin_infobar_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_othertext), bmp_active_skin->properties.mainwin_infobar_x, bmp_active_skin->properties.mainwin_infobar_y); if (bmp_active_skin->properties.mainwin_number_0_x && bmp_active_skin->properties.mainwin_number_0_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_minus_num), bmp_active_skin->properties.mainwin_number_0_x, bmp_active_skin->properties.mainwin_number_0_y); if (bmp_active_skin->properties.mainwin_number_1_x && bmp_active_skin->properties.mainwin_number_1_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_10min_num), bmp_active_skin->properties.mainwin_number_1_x, bmp_active_skin->properties.mainwin_number_1_y); if (bmp_active_skin->properties.mainwin_number_2_x && bmp_active_skin->properties.mainwin_number_2_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_min_num), bmp_active_skin->properties.mainwin_number_2_x, bmp_active_skin->properties.mainwin_number_2_y); if (bmp_active_skin->properties.mainwin_number_3_x && bmp_active_skin->properties.mainwin_number_3_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_10sec_num), bmp_active_skin->properties.mainwin_number_3_x, bmp_active_skin->properties.mainwin_number_3_y); if (bmp_active_skin->properties.mainwin_number_4_x && bmp_active_skin->properties.mainwin_number_4_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_sec_num), bmp_active_skin->properties.mainwin_number_4_x, bmp_active_skin->properties.mainwin_number_4_y); if (bmp_active_skin->properties.mainwin_playstatus_x && bmp_active_skin->properties.mainwin_playstatus_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_playstatus, bmp_active_skin->properties.mainwin_playstatus_x, bmp_active_skin->properties.mainwin_playstatus_y); if (bmp_active_skin->properties.mainwin_volume_x && bmp_active_skin->properties.mainwin_volume_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_volume), bmp_active_skin->properties.mainwin_volume_x, bmp_active_skin->properties.mainwin_volume_y); if (bmp_active_skin->properties.mainwin_balance_x && bmp_active_skin->properties.mainwin_balance_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_balance), bmp_active_skin->properties.mainwin_balance_x, bmp_active_skin->properties.mainwin_balance_y); if (bmp_active_skin->properties.mainwin_position_x && bmp_active_skin->properties.mainwin_position_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_position), bmp_active_skin->properties.mainwin_position_x, bmp_active_skin->properties.mainwin_position_y); if (bmp_active_skin->properties.mainwin_previous_x && bmp_active_skin->properties.mainwin_previous_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), mainwin_rew, bmp_active_skin->properties.mainwin_previous_x, bmp_active_skin->properties.mainwin_previous_y); if (bmp_active_skin->properties.mainwin_play_x && bmp_active_skin->properties.mainwin_play_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_play), bmp_active_skin->properties.mainwin_play_x, bmp_active_skin->properties.mainwin_play_y); if (bmp_active_skin->properties.mainwin_pause_x && bmp_active_skin->properties.mainwin_pause_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_pause), bmp_active_skin->properties.mainwin_pause_x, bmp_active_skin->properties.mainwin_pause_y); if (bmp_active_skin->properties.mainwin_stop_x && bmp_active_skin->properties.mainwin_stop_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_stop), bmp_active_skin->properties.mainwin_stop_x, bmp_active_skin->properties.mainwin_stop_y); if (bmp_active_skin->properties.mainwin_next_x && bmp_active_skin->properties.mainwin_next_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_fwd), bmp_active_skin->properties.mainwin_next_x, bmp_active_skin->properties.mainwin_next_y); if (bmp_active_skin->properties.mainwin_eject_x && bmp_active_skin->properties.mainwin_eject_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_eject), bmp_active_skin->properties.mainwin_eject_x, bmp_active_skin->properties.mainwin_eject_y); if (bmp_active_skin->properties.mainwin_eqbutton_x && bmp_active_skin->properties.mainwin_eqbutton_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_eq), bmp_active_skin->properties.mainwin_eqbutton_x, bmp_active_skin->properties.mainwin_eqbutton_y); if (bmp_active_skin->properties.mainwin_plbutton_x && bmp_active_skin->properties.mainwin_plbutton_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_pl), bmp_active_skin->properties.mainwin_plbutton_x, bmp_active_skin->properties.mainwin_plbutton_y); if (bmp_active_skin->properties.mainwin_shuffle_x && bmp_active_skin->properties.mainwin_shuffle_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_shuffle), bmp_active_skin->properties.mainwin_shuffle_x, bmp_active_skin->properties.mainwin_shuffle_y); if (bmp_active_skin->properties.mainwin_repeat_x && bmp_active_skin->properties.mainwin_repeat_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_repeat), bmp_active_skin->properties.mainwin_repeat_x, bmp_active_skin->properties.mainwin_repeat_y); if (bmp_active_skin->properties.mainwin_about_x && bmp_active_skin->properties.mainwin_about_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_about), bmp_active_skin->properties.mainwin_about_x, bmp_active_skin->properties.mainwin_about_y); if (bmp_active_skin->properties.mainwin_minimize_x && bmp_active_skin->properties.mainwin_minimize_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_minimize), cfg.player_shaded ? 244 : bmp_active_skin->properties.mainwin_minimize_x, cfg.player_shaded ? 3 : bmp_active_skin->properties.mainwin_minimize_y); if (bmp_active_skin->properties.mainwin_shade_x && bmp_active_skin->properties.mainwin_shade_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_shade), cfg.player_shaded ? 254 : bmp_active_skin->properties.mainwin_shade_x, cfg.player_shaded ? 3 : bmp_active_skin->properties.mainwin_shade_y); if (bmp_active_skin->properties.mainwin_close_x && bmp_active_skin->properties.mainwin_close_y) gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_close), cfg.player_shaded ? 264 : bmp_active_skin->properties.mainwin_close_x, cfg.player_shaded ? 3 : bmp_active_skin->properties.mainwin_close_y); mainwin_refresh_visible(); /* window size, mainwinWidth && mainwinHeight properties */ if (bmp_active_skin->properties.mainwin_height && bmp_active_skin->properties.mainwin_width) { gint width, height; gdk_window_get_size(mainwin->window, &width, &height); if (width == bmp_active_skin->properties.mainwin_width * (cfg.doublesize + 1) && height == bmp_active_skin->properties.mainwin_height * (cfg.doublesize + 1)) return; dock_window_resize(GTK_WINDOW(mainwin), cfg.player_shaded ? MAINWIN_SHADED_WIDTH * (cfg.doublesize + 1) : bmp_active_skin->properties.mainwin_width * (cfg.doublesize + 1), cfg.player_shaded ? MAINWIN_SHADED_HEIGHT * (cfg.doublesize + 1) : bmp_active_skin->properties.mainwin_height * (cfg.doublesize + 1), bmp_active_skin->properties.mainwin_width * (cfg.doublesize + 1), bmp_active_skin->properties.mainwin_height * (cfg.doublesize + 1)); gdk_flush(); } } void mainwin_set_song_info(gint bitrate, gint frequency, gint n_channels) { gchar *text; gchar *title; Playlist *playlist = playlist_get_active(); playback_set_sample_params(bitrate, frequency, n_channels); GDK_THREADS_ENTER(); if (bitrate != -1) { bitrate /= 1000; if (bitrate < 1000) { /* Show bitrate in 1000s */ text = g_strdup_printf("%3d", bitrate); ui_skinned_textbox_set_text(mainwin_rate_text, text); } else { /* Show bitrate in 100,000s */ text = g_strdup_printf("%2dH", bitrate / 100); ui_skinned_textbox_set_text(mainwin_rate_text, text); } } else ui_skinned_textbox_set_text(mainwin_rate_text, _("VBR")); /* Show sampling frequency in kHz */ text = g_strdup_printf("%2d", frequency / 1000); ui_skinned_textbox_set_text(mainwin_freq_text, text); ui_skinned_monostereo_set_num_channels(mainwin_monostereo, n_channels); if (!playback_get_paused() && mainwin_playstatus != NULL) ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_PLAY); if (bmp_active_skin && bmp_active_skin->properties.mainwin_othertext) { if (bitrate != -1) text = g_strdup_printf("%d kbps, %0.1f kHz, %s", bitrate, (gfloat) frequency / 1000, (n_channels > 1) ? _("stereo") : _("mono")); else text = g_strdup_printf("VBR, %0.1f kHz, %s", (gfloat) frequency / 1000, (n_channels > 1) ? _("stereo") : _("mono")); ui_skinned_textbox_set_text(mainwin_othertext, text); } title = playlist_get_info_text(playlist); mainwin_set_song_title(title); g_free(title); GDK_THREADS_LEAVE(); } void mainwin_clear_song_info(void) { if (!mainwin) return; /* clear title */ mainwin_set_song_title(NULL); /* clear sampling parameters */ playback_set_sample_params(0, 0, 0); UI_SKINNED_HORIZONTAL_SLIDER(mainwin_position)->pressed = FALSE; UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->pressed = FALSE; /* clear sampling parameter displays */ ui_skinned_textbox_set_text(mainwin_rate_text, " "); ui_skinned_textbox_set_text(mainwin_freq_text, " "); ui_skinned_monostereo_set_num_channels(mainwin_monostereo, 0); if (mainwin_playstatus != NULL) ui_skinned_playstatus_set_status(mainwin_playstatus, STATUS_STOP); mainwin_refresh_visible(); playlistwin_hide_timer(); ui_vis_clear_data(mainwin_vis); ui_svis_clear_data(mainwin_svis); } void mainwin_disable_seekbar(void) { if (!mainwin) return; gtk_widget_hide(mainwin_position); gtk_widget_hide(mainwin_sposition); } static gboolean mainwin_mouse_button_release(GtkWidget * widget, GdkEventButton * event, gpointer callback_data) { if (dock_is_moving(GTK_WINDOW(mainwin))) { dock_move_release(GTK_WINDOW(mainwin)); } return FALSE; } void mainwin_scrolled(GtkWidget *widget, GdkEventScroll *event, gpointer callback_data) { Playlist *playlist = playlist_get_active(); switch (event->direction) { case GDK_SCROLL_UP: mainwin_set_volume_diff(cfg.mouse_change); break; case GDK_SCROLL_DOWN: mainwin_set_volume_diff(-cfg.mouse_change); break; case GDK_SCROLL_LEFT: if (playlist_get_current_length(playlist) != -1) playback_seek(CLAMP(playback_get_time() - 1000, 0, playlist_get_current_length(playlist)) / 1000); break; case GDK_SCROLL_RIGHT: if (playlist_get_current_length(playlist) != -1) playback_seek(CLAMP(playback_get_time() + 1000, 0, playlist_get_current_length(playlist)) / 1000); break; } } static gboolean mainwin_widget_contained(GdkEventButton *event, int x, int y, int w, int h) { if ((event->x > x && event->y > y) && (event->x < x+w && event->y < y+h)) return TRUE; return FALSE; } static gboolean mainwin_mouse_button_press(GtkWidget * widget, GdkEventButton * event, gpointer callback_data) { if (cfg.doublesize) { /* * A hack to make doublesize transparent to callbacks. * We should make a copy of this data instead of * tampering with the data we get from gtk+ */ event->x /= 2; event->y /= 2; } if (event->button == 1 && event->type == GDK_BUTTON_PRESS && (cfg.easy_move || event->y < 14)) { gtk_window_present(GTK_WINDOW(mainwin)); dock_move_press(dock_window_list, GTK_WINDOW(mainwin), event, TRUE); } else if (event->button == 1 && event->type == GDK_2BUTTON_PRESS && event->y < 14) { mainwin_set_shade(!cfg.player_shaded); if (dock_is_moving(GTK_WINDOW(mainwin))) dock_move_release(GTK_WINDOW(mainwin)); } if (event->button == 3) { /* Pop up playback menu if right clicked over playback-control widgets, * otherwise popup general menu */ if (mainwin_widget_contained(event, bmp_active_skin->properties.mainwin_position_x, bmp_active_skin->properties.mainwin_position_y, 248, 10) || mainwin_widget_contained(event, bmp_active_skin->properties.mainwin_previous_x, bmp_active_skin->properties.mainwin_previous_y, 23, 18) || mainwin_widget_contained(event, bmp_active_skin->properties.mainwin_play_x, bmp_active_skin->properties.mainwin_play_y, 23, 18) || mainwin_widget_contained(event, bmp_active_skin->properties.mainwin_pause_x, bmp_active_skin->properties.mainwin_pause_y, 23, 18) || mainwin_widget_contained(event, bmp_active_skin->properties.mainwin_stop_x, bmp_active_skin->properties.mainwin_stop_y, 23, 18) || mainwin_widget_contained(event, bmp_active_skin->properties.mainwin_next_x, bmp_active_skin->properties.mainwin_next_y, 23, 18)) { ui_manager_popup_menu_show(GTK_MENU(mainwin_playback_menu), event->x_root, event->y_root, 3, event->time); } else { /* * Pop up the main menu a few pixels down. * This will avoid that anything is selected * if one right-clicks to focus the window * without raising it. * ***MD I think the above is stupid, people don't expect this * */ ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu), event->x_root, event->y_root, 3, event->time); } } return FALSE; } static gboolean mainwin_keypress(GtkWidget * grab_widget, GdkEventKey * event, gpointer data) { Playlist *playlist = playlist_get_active(); switch (event->keyval) { case GDK_Up: case GDK_KP_Up: case GDK_KP_8: mainwin_set_volume_diff(2); break; case GDK_Down: case GDK_KP_Down: case GDK_KP_2: mainwin_set_volume_diff(-2); break; case GDK_Left: case GDK_KP_Left: case GDK_KP_7: if (playlist_get_current_length(playlist) != -1) playback_seek(CLAMP (playback_get_time() - 5000, 0, playlist_get_current_length(playlist)) / 1000); break; case GDK_Right: case GDK_KP_Right: case GDK_KP_9: if (playlist_get_current_length(playlist) != -1) playback_seek(CLAMP (playback_get_time() + 5000, 0, playlist_get_current_length(playlist)) / 1000); break; case GDK_KP_4: playlist_prev(playlist); break; case GDK_KP_6: playlist_next(playlist); break; case GDK_KP_Insert: ui_jump_to_track(); break; case GDK_Return: case GDK_KP_Enter: case GDK_KP_5: mainwin_play_pushed(); break; case GDK_space: playback_pause(); break; case GDK_Escape: mainwin_minimize_cb(); break; case GDK_Tab: if (event->state & GDK_CONTROL_MASK) equalizerwin_real_show(); break; case GDK_c: if (event->state & GDK_CONTROL_MASK) { Playlist *playlist = playlist_get_active(); gint pos = playlist_get_position(playlist); gchar *title = playlist_get_songtitle(playlist, pos); if (title != NULL) { GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); gtk_clipboard_set_text(clip, title, -1); gtk_clipboard_store(clip); } return TRUE; } return FALSE; default: return FALSE; } return TRUE; } static void mainwin_jump_to_time_cb(GtkWidget * widget, GtkWidget * entry) { guint min = 0, sec = 0, params; gint time; Playlist *playlist = playlist_get_active(); params = sscanf(gtk_entry_get_text(GTK_ENTRY(entry)), "%u:%u", &min, &sec); if (params == 2) time = (min * 60) + sec; else if (params == 1) time = min; else return; if (playlist_get_current_length(playlist) > -1 && time <= (playlist_get_current_length(playlist) / 1000)) { playback_seek(time); gtk_widget_destroy(mainwin_jtt); } } void mainwin_jump_to_time(void) { GtkWidget *vbox, *hbox_new, *hbox_total; GtkWidget *time_entry, *label, *bbox, *jump, *cancel; guint tindex; gchar time_str[10]; if (!playback_get_playing()) { report_error("JIT can't be launched when no track is being played.\n"); return; } if (mainwin_jtt) { gtk_window_present(GTK_WINDOW(mainwin_jtt)); return; } mainwin_jtt = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_type_hint(GTK_WINDOW(mainwin_jtt), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_title(GTK_WINDOW(mainwin_jtt), _("Jump to Time")); gtk_window_set_position(GTK_WINDOW(mainwin_jtt), GTK_WIN_POS_CENTER); gtk_window_set_transient_for(GTK_WINDOW(mainwin_jtt), GTK_WINDOW(mainwin)); g_signal_connect(mainwin_jtt, "destroy", G_CALLBACK(gtk_widget_destroyed), &mainwin_jtt); gtk_container_border_width(GTK_CONTAINER(mainwin_jtt), 10); vbox = gtk_vbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(mainwin_jtt), vbox); hbox_new = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox_new, TRUE, TRUE, 5); time_entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hbox_new), time_entry, FALSE, FALSE, 5); g_signal_connect(time_entry, "activate", G_CALLBACK(mainwin_jump_to_time_cb), time_entry); gtk_widget_set_size_request(time_entry, 70, -1); label = gtk_label_new(_("minutes:seconds")); gtk_box_pack_start(GTK_BOX(hbox_new), label, FALSE, FALSE, 5); hbox_total = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox_total, TRUE, TRUE, 5); gtk_widget_show(hbox_total); /* FIXME: Disable display of current track length. It's not updated when track changes */ #if 0 label = gtk_label_new(_("Track length:")); gtk_box_pack_start(GTK_BOX(hbox_total), label, FALSE, FALSE, 5); len = playlist_get_current_length() / 1000; g_snprintf(time_str, sizeof(time_str), "%u:%2.2u", len / 60, len % 60); label = gtk_label_new(time_str); gtk_box_pack_start(GTK_BOX(hbox_total), label, FALSE, FALSE, 10); #endif bbox = gtk_hbutton_box_new(); gtk_box_pack_start(GTK_BOX(vbox), bbox, TRUE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5); cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL); GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT); gtk_container_add(GTK_CONTAINER(bbox), cancel); g_signal_connect_swapped(cancel, "clicked", G_CALLBACK(gtk_widget_destroy), mainwin_jtt); jump = gtk_button_new_from_stock(GTK_STOCK_JUMP_TO); GTK_WIDGET_SET_FLAGS(jump, GTK_CAN_DEFAULT); gtk_container_add(GTK_CONTAINER(bbox), jump); g_signal_connect(jump, "clicked", G_CALLBACK(mainwin_jump_to_time_cb), time_entry); tindex = playback_get_time() / 1000; g_snprintf(time_str, sizeof(time_str), "%u:%2.2u", tindex / 60, tindex % 60); gtk_entry_set_text(GTK_ENTRY(time_entry), time_str); gtk_entry_select_region(GTK_ENTRY(time_entry), 0, strlen(time_str)); gtk_widget_show_all(mainwin_jtt); gtk_widget_grab_focus(time_entry); gtk_widget_grab_default(jump); } /* * Rewritten 09/13/06: * * Remove all of this flaky iter/sourcelist/strsplit stuff. * All we care about is the filepath. * * We can figure this out and easily pass it to g_filename_from_uri(). * - nenolod */ void mainwin_drag_data_received(GtkWidget * widget, GdkDragContext * context, gint x, gint y, GtkSelectionData * selection_data, guint info, guint time, gpointer user_data) { Playlist *playlist = playlist_get_active(); g_return_if_fail(selection_data != NULL); g_return_if_fail(selection_data->data != NULL); if (str_has_prefix_nocase((gchar *) selection_data->data, "fonts:///")) { gchar *path = (gchar *) selection_data->data; gchar *decoded = g_filename_from_uri(path, NULL, NULL); if (decoded == NULL) return; cfg.playlist_font = g_strconcat(decoded, strrchr(cfg.playlist_font, ' '), NULL); ui_skinned_playlist_set_font(cfg.playlist_font); playlistwin_update_list(playlist); g_free(decoded); return; } playlist_clear(playlist); playlist_add_url(playlist, (gchar *) selection_data->data); playback_initiate(); } static void on_add_url_add_clicked(GtkWidget * widget, GtkWidget * entry) { const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); if (text && *text) playlist_add_url(playlist_get_active(), text); } static void on_add_url_ok_clicked(GtkWidget * widget, GtkWidget * entry) { Playlist *playlist = playlist_get_active(); const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry)); if (text && *text) { playlist_clear(playlist); playlist_add_url(playlist, text); playback_initiate(); } } static void on_visibility_warning_toggle(GtkToggleButton *tbt, gpointer unused) { cfg.warn_about_win_visibility = !gtk_toggle_button_get_active(tbt); } static void on_visibility_warning_response(GtkDialog *dlg, gint r_id, gpointer unused) { switch (r_id) { case GTK_RESPONSE_OK: mainwin_show(TRUE); break; case GTK_RESPONSE_CANCEL: default: break; } gtk_widget_destroy(GTK_WIDGET(dlg)); } void mainwin_show_visibility_warning(void) { if (cfg.warn_about_win_visibility) { GtkWidget *label, *checkbt, *vbox; GtkWidget *warning_dlg = gtk_dialog_new_with_buttons( _("Audacious - visibility warning") , GTK_WINDOW(mainwin) , GTK_DIALOG_DESTROY_WITH_PARENT , _("Show main player window") , GTK_RESPONSE_OK , _("Ignore") , GTK_RESPONSE_CANCEL , NULL ); vbox = gtk_vbox_new( FALSE , 4 ); gtk_container_set_border_width( GTK_CONTAINER(vbox) , 4 ); gtk_box_pack_start( GTK_BOX(GTK_DIALOG(warning_dlg)->vbox) , vbox , TRUE , TRUE , 0 ); label = gtk_label_new( _("Audacious has been started with all of its windows hidden.\n" "You may want to show the player window again to control Audacious; " "otherwise, you'll have to control it remotely via audtool or " "enabled plugins (such as the statusicon plugin).") ); gtk_label_set_line_wrap( GTK_LABEL(label) , TRUE ); gtk_misc_set_alignment( GTK_MISC(label) , 0.0 , 0.0 ); checkbt = gtk_check_button_new_with_label( _("Always ignore, show/hide is controlled remotely") ); gtk_box_pack_start( GTK_BOX(vbox) , label , TRUE , TRUE , 0 ); gtk_box_pack_start( GTK_BOX(vbox) , checkbt , TRUE , TRUE , 0 ); g_signal_connect( G_OBJECT(checkbt) , "toggled" , G_CALLBACK(on_visibility_warning_toggle) , NULL ); g_signal_connect( G_OBJECT(warning_dlg) , "response" , G_CALLBACK(on_visibility_warning_response) , NULL ); gtk_widget_show_all(warning_dlg); } } void mainwin_show_add_url_window(void) { static GtkWidget *url_window = NULL; if (!url_window) { url_window = util_add_url_dialog_new(_("Enter location to play:"), G_CALLBACK(on_add_url_ok_clicked), G_CALLBACK(on_add_url_add_clicked)); gtk_window_set_transient_for(GTK_WINDOW(url_window), GTK_WINDOW(mainwin)); g_signal_connect(url_window, "destroy", G_CALLBACK(gtk_widget_destroyed), &url_window); } gtk_window_present(GTK_WINDOW(url_window)); } static void check_set( GtkActionGroup * action_group , const gchar * action_name , gboolean is_on ) { /* check_set noew uses gtkaction */ GtkAction *action = gtk_action_group_get_action( action_group , action_name ); if ( action != NULL ) gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , is_on ); return; } void mainwin_eject_pushed(void) { run_filebrowser(PLAY_BUTTON); } void mainwin_rev_pushed(void) { g_get_current_time(&cb_time); seek_initial_pos = ui_skinned_horizontal_slider_get_position(mainwin_position); seek_state = MAINWIN_SEEK_REV; } void mainwin_rev_release(void) { GTimeVal now_time; GTimeVal delta_time; gulong now_dur; g_get_current_time(&now_time); delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec; delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec; now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000)); if ( now_dur <= TRISTATE_THRESHOLD ) { /* interpret as 'skip to previous song' */ playlist_prev(playlist_get_active()); } else { /* interpret as 'seek' */ mainwin_position_release_cb( mainwin_position, ui_skinned_horizontal_slider_get_position(mainwin_position) ); } seek_state = MAINWIN_SEEK_NIL; } void mainwin_fwd_pushed(void) { g_get_current_time(&cb_time); seek_initial_pos = ui_skinned_horizontal_slider_get_position(mainwin_position); seek_state = MAINWIN_SEEK_FWD; } void mainwin_fwd_release(void) { GTimeVal now_time; GTimeVal delta_time; gulong now_dur; g_get_current_time(&now_time); delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec; delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec; now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000)); if ( now_dur <= TRISTATE_THRESHOLD ) { /* interpret as 'skip to next song' */ playlist_next(playlist_get_active()); } else { /* interpret as 'seek' */ mainwin_position_release_cb( mainwin_position, ui_skinned_horizontal_slider_get_position(mainwin_position) ); } seek_state = MAINWIN_SEEK_NIL; } void mainwin_play_pushed(void) { if (ab_position_a != -1) playback_seek(ab_position_a / 1000); if (playback_get_paused()) { playback_pause(); return; } if (playlist_get_length(playlist_get_active())) playback_initiate(); else mainwin_eject_pushed(); } void mainwin_stop_pushed(void) { ip_data.stop = TRUE; playback_stop(); mainwin_clear_song_info(); ab_position_a = ab_position_b = -1; ip_data.stop = FALSE; } void mainwin_shuffle_pushed(gboolean toggled) { check_set( toggleaction_group_others , "playback shuffle" , toggled ); } void mainwin_shuffle_pushed_cb(void) { mainwin_shuffle_pushed(UI_SKINNED_BUTTON(mainwin_shuffle)->inside); } void mainwin_repeat_pushed(gboolean toggled) { check_set( toggleaction_group_others , "playback repeat" , toggled ); } void mainwin_repeat_pushed_cb(void) { mainwin_repeat_pushed(UI_SKINNED_BUTTON(mainwin_repeat)->inside); } void mainwin_equalizer_pushed_cb(void) { mainwin_eq_pushed(UI_SKINNED_BUTTON(mainwin_eq)->inside); } void mainwin_playlist_pushed_cb(void) { mainwin_pl_pushed(UI_SKINNED_BUTTON(mainwin_pl)->inside); } void mainwin_eq_pushed(gboolean toggled) { equalizerwin_show(toggled); } void mainwin_pl_pushed(gboolean toggled) { if (toggled) playlistwin_show(); else playlistwin_hide(); } gint mainwin_spos_frame_cb(gint pos) { if (mainwin_sposition) { gint x = 0; if (pos < 6) x = 17; else if (pos < 9) x = 20; else x = 23; UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->knob_nx = x; UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->knob_px = x; } return 1; } void mainwin_spos_motion_cb(GtkWidget *widget, gint pos) { gint time; gchar *time_msg; Playlist *playlist = playlist_get_active(); pos--; time = ((playlist_get_current_length(playlist) / 1000) * pos) / 12; if (cfg.timer_mode == TIMER_REMAINING) { time = (playlist_get_current_length(playlist) / 1000) - time; time_msg = g_strdup_printf("-%2.2d", time / 60); ui_skinned_textbox_set_text(mainwin_stime_min, time_msg); g_free(time_msg); } else { time_msg = g_strdup_printf(" %2.2d", time / 60); ui_skinned_textbox_set_text(mainwin_stime_min, time_msg); g_free(time_msg); } time_msg = g_strdup_printf("%2.2d", time % 60); ui_skinned_textbox_set_text(mainwin_stime_sec, time_msg); g_free(time_msg); } void mainwin_spos_release_cb(GtkWidget *widget, gint pos) { playback_seek(((playlist_get_current_length(playlist_get_active()) / 1000) * (pos - 1)) / 12); } void mainwin_position_motion_cb(GtkWidget *widget, gint pos) { gint length, time; gchar *seek_msg; length = playlist_get_current_length(playlist_get_active()) / 1000; time = (length * pos) / 219; seek_msg = g_strdup_printf(_("Seek to: %d:%-2.2d/%d:%-2.2d (%d%%)"), time / 60, time % 60, length / 60, length % 60, (length != 0) ? (time * 100) / length : 0); mainwin_lock_info_text(seek_msg); g_free(seek_msg); } void mainwin_position_release_cb(GtkWidget *widget, gint pos) { gint length, time; length = playlist_get_current_length(playlist_get_active()) / 1000; time = (length * pos) / 219; playback_seek(time); mainwin_release_info_text(); } gint mainwin_volume_frame_cb(gint pos) { return (gint) rint((pos / 52.0) * 28); } void mainwin_adjust_volume_motion(gint v) { gchar *volume_msg; setting_volume = TRUE; volume_msg = g_strdup_printf(_("Volume: %d%%"), v); mainwin_lock_info_text(volume_msg); g_free(volume_msg); if (balance < 0) input_set_volume(v, (v * (100 - abs(balance))) / 100); else if (balance > 0) input_set_volume((v * (100 - abs(balance))) / 100, v); else input_set_volume(v, v); } void mainwin_adjust_volume_release(void) { mainwin_release_info_text(); setting_volume = FALSE; read_volume(VOLUME_ADJUSTED); } void mainwin_adjust_balance_motion(gint b) { gchar *balance_msg; gint v, pvl, pvr; setting_volume = TRUE; balance = b; input_get_volume(&pvl, &pvr); v = MAX(pvl, pvr); if (b < 0) { balance_msg = g_strdup_printf(_("Balance: %d%% left"), -b); input_set_volume(v, (gint) rint(((100 + b) / 100.0) * v)); } else if (b == 0) { balance_msg = g_strdup_printf(_("Balance: center")); input_set_volume(v, v); } else { /* b > 0 */ balance_msg = g_strdup_printf(_("Balance: %d%% right"), b); input_set_volume((gint) rint(((100 - b) / 100.0) * v), v); } mainwin_lock_info_text(balance_msg); g_free(balance_msg); } void mainwin_adjust_balance_release(void) { mainwin_release_info_text(); setting_volume = FALSE; read_volume(VOLUME_ADJUSTED); } void mainwin_set_volume_slider(gint percent) { ui_skinned_horizontal_slider_set_position(mainwin_volume, (gint) rint((percent * 51) / 100.0)); } void mainwin_set_balance_slider(gint percent) { ui_skinned_horizontal_slider_set_position(mainwin_balance, (gint) rint(((percent * 12) / 100.0) + 12)); } void mainwin_volume_motion_cb(GtkWidget *widget, gint pos) { gint vol = (pos * 100) / 51; mainwin_adjust_volume_motion(vol); equalizerwin_set_volume_slider(vol); } void mainwin_volume_release_cb(GtkWidget *widget, gint pos) { mainwin_adjust_volume_release(); } gint mainwin_balance_frame_cb(gint pos) { return ((abs(pos - 12) * 28) / 13); } void mainwin_balance_motion_cb(GtkWidget *widget, gint pos) { gint bal = ((pos - 12) * 100) / 12; mainwin_adjust_balance_motion(bal); equalizerwin_set_balance_slider(bal); } void mainwin_balance_release_cb(GtkWidget *widget, gint pos) { mainwin_adjust_volume_release(); } void mainwin_set_volume_diff(gint diff) { gint vl, vr, vol; input_get_volume(&vl, &vr); vol = MAX(vl, vr); vol = CLAMP(vol + diff, 0, 100); mainwin_adjust_volume_motion(vol); setting_volume = FALSE; mainwin_set_volume_slider(vol); equalizerwin_set_volume_slider(vol); read_volume(VOLUME_SET); } void mainwin_set_balance_diff(gint diff) { gint b; b = CLAMP(balance + diff, -100, 100); mainwin_adjust_balance_motion(b); setting_volume = FALSE; mainwin_set_balance_slider(b); equalizerwin_set_balance_slider(b); read_volume(VOLUME_SET); } void mainwin_show(gboolean show) { if (show) mainwin_real_show(); else mainwin_real_hide(); } void mainwin_real_show(void) { cfg.player_visible = TRUE; check_set( toggleaction_group_others , "show player" , TRUE ); if (cfg.player_shaded) ui_vis_clear_data(mainwin_vis); mainwin_set_shape_mask(); if (cfg.show_wm_decorations) { if (cfg.player_x != -1 && cfg.save_window_position) gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y); gtk_widget_show(mainwin); return; } if (nullmask) { g_object_unref(nullmask); nullmask = NULL; } gtk_window_resize(GTK_WINDOW(mainwin), !bmp_active_skin->properties.mainwin_width ? PLAYER_WIDTH : bmp_active_skin->properties.mainwin_width, !bmp_active_skin->properties.mainwin_height ? PLAYER_HEIGHT : bmp_active_skin->properties.mainwin_height); if (cfg.player_x != -1 && cfg.save_window_position) gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y); gtk_window_present(GTK_WINDOW(mainwin)); mainwin_refresh_hints(); } void mainwin_real_hide(void) { GdkGC *gc; GdkColor pattern; check_set( toggleaction_group_others , "show player", FALSE); if (cfg.player_shaded) ui_svis_clear_data(mainwin_svis); if (!cfg.show_wm_decorations) { nullmask = gdk_pixmap_new(mainwin->window, 20, 20, 1); gc = gdk_gc_new(nullmask); pattern.pixel = 0; gdk_gc_set_foreground(gc, &pattern); gdk_draw_rectangle(nullmask, gc, TRUE, 0, 0, 20, 20); g_object_unref(gc); gtk_widget_shape_combine_mask(mainwin, nullmask, 0, 0); } gtk_widget_hide(mainwin); cfg.player_visible = FALSE; } void mainwin_set_stopaftersong(gboolean stop) { cfg.stopaftersong = stop; check_set(toggleaction_group_others, "stop after current song", cfg.stopaftersong); } void mainwin_set_noplaylistadvance(gboolean no_advance) { cfg.no_playlist_advance = no_advance; check_set(toggleaction_group_others, "playback no playlist advance", cfg.no_playlist_advance); } static void mainwin_set_doublesize(gboolean doublesize) { gint height; if (cfg.player_shaded) height = MAINWIN_SHADED_HEIGHT; else height = bmp_active_skin->properties.mainwin_height; mainwin_set_shape_mask(); dock_window_resize(GTK_WINDOW(mainwin), cfg.player_shaded ? MAINWIN_SHADED_WIDTH : bmp_active_skin->properties.mainwin_width, cfg.player_shaded ? MAINWIN_SHADED_HEIGHT : bmp_active_skin->properties.mainwin_height, bmp_active_skin->properties.mainwin_width * 2, bmp_active_skin->properties.mainwin_height * 2); GList *iter; for (iter = GTK_FIXED (SKINNED_WINDOW(mainwin)->fixed)->children; iter; iter = g_list_next (iter)) { GtkFixedChild *child_data = (GtkFixedChild *) iter->data; GtkWidget *child = child_data->widget; g_signal_emit_by_name(child, "toggle-double-size"); } mainwin_refresh_hints(); } void set_doublesize(gboolean doublesize) { cfg.doublesize = doublesize; mainwin_set_doublesize(doublesize); if (cfg.eq_doublesize_linked) equalizerwin_set_doublesize(doublesize); } void mainwin_general_menu_callback(gpointer data, guint action, GtkWidget * item) { Playlist *playlist = playlist_get_active(); switch (action) { case MAINWIN_GENERAL_PREFS: show_prefs_window(); break; case MAINWIN_GENERAL_ABOUT: show_about_window(); break; case MAINWIN_GENERAL_PLAYFILE: run_filebrowser(NO_PLAY_BUTTON); break; case MAINWIN_GENERAL_PLAYLOCATION: mainwin_show_add_url_window(); break; case MAINWIN_GENERAL_FILEINFO: playlist_fileinfo_current(playlist); break; case MAINWIN_GENERAL_FOCUSPLWIN: gtk_window_present(GTK_WINDOW(playlistwin)); break; case MAINWIN_GENERAL_SHOWMWIN: mainwin_show(GTK_CHECK_MENU_ITEM(item)->active); break; case MAINWIN_GENERAL_SHOWPLWIN: if (GTK_CHECK_MENU_ITEM(item)->active) playlistwin_show(); else playlistwin_hide(); break; case MAINWIN_GENERAL_SHOWEQWIN: if (GTK_CHECK_MENU_ITEM(item)->active) equalizerwin_real_show(); else equalizerwin_real_hide(); break; case MAINWIN_GENERAL_PREV: playlist_prev(playlist); break; case MAINWIN_GENERAL_PLAY: mainwin_play_pushed(); break; case MAINWIN_GENERAL_PAUSE: playback_pause(); break; case MAINWIN_GENERAL_STOP: mainwin_stop_pushed(); break; case MAINWIN_GENERAL_NEXT: playlist_next(playlist); break; case MAINWIN_GENERAL_BACK5SEC: if (playback_get_playing() && playlist_get_current_length(playlist) != -1) playback_seek_relative(-5); break; case MAINWIN_GENERAL_FWD5SEC: if (playback_get_playing() && playlist_get_current_length(playlist) != -1) playback_seek_relative(5); break; case MAINWIN_GENERAL_START: playlist_set_position(playlist, 0); break; case MAINWIN_GENERAL_JTT: mainwin_jump_to_time(); break; case MAINWIN_GENERAL_JTF: ui_jump_to_track(); break; case MAINWIN_GENERAL_EXIT: mainwin_quit_cb(); break; case MAINWIN_GENERAL_SETAB: if (playlist_get_current_length(playlist) != -1) { if (ab_position_a == -1) { ab_position_a = playback_get_time(); ab_position_b = -1; mainwin_lock_info_text("'Loop-Point A Position' set."); } else if (ab_position_b == -1) { int time = playback_get_time(); if (time > ab_position_a) ab_position_b = time; mainwin_release_info_text(); } else { ab_position_a = playback_get_time(); ab_position_b = -1; mainwin_lock_info_text("'Loop-Point A Position' reset."); } } break; case MAINWIN_GENERAL_CLEARAB: if (playlist_get_current_length(playlist) != -1) { ab_position_a = ab_position_b = -1; mainwin_release_info_text(); } break; case MAINWIN_GENERAL_NEW_PL: { Playlist *new_pl = playlist_new(); playlist_add_playlist(new_pl); playlist_select_playlist(new_pl); } break; case MAINWIN_GENERAL_PREV_PL: playlist_select_prev(); break; case MAINWIN_GENERAL_NEXT_PL: playlist_select_next(); break; } } static void mainwin_mr_change(GtkWidget *widget, MenuRowItem i) { switch (i) { case MENUROW_OPTIONS: mainwin_lock_info_text(_("Options Menu")); break; case MENUROW_ALWAYS: if (UI_SKINNED_MENUROW(mainwin_menurow)->always_selected) mainwin_lock_info_text(_("Disable 'Always On Top'")); else mainwin_lock_info_text(_("Enable 'Always On Top'")); break; case MENUROW_FILEINFOBOX: mainwin_lock_info_text(_("File Info Box")); break; case MENUROW_DOUBLESIZE: if (UI_SKINNED_MENUROW(mainwin_menurow)->doublesize_selected) mainwin_lock_info_text(_("Disable 'Doublesize'")); else mainwin_lock_info_text(_("Enable 'Doublesize'")); break; case MENUROW_VISUALIZATION: mainwin_lock_info_text(_("Visualization Menu")); break; case MENUROW_NONE: break; } } static void mainwin_mr_release(GtkWidget *widget, MenuRowItem i) { GdkModifierType modmask; gint x, y; switch (i) { case MENUROW_OPTIONS: gdk_window_get_pointer(NULL, &x, &y, &modmask); ui_manager_popup_menu_show(GTK_MENU(mainwin_view_menu), x, y, 1, GDK_CURRENT_TIME); break; case MENUROW_ALWAYS: gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(gtk_action_group_get_action( toggleaction_group_others , "view always on top" )) , UI_SKINNED_MENUROW(mainwin_menurow)->always_selected ); break; case MENUROW_FILEINFOBOX: playlist_fileinfo_current(playlist_get_active()); break; case MENUROW_DOUBLESIZE: gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(gtk_action_group_get_action( toggleaction_group_others , "view doublesize" )) , UI_SKINNED_MENUROW(mainwin_menurow)->doublesize_selected ); break; case MENUROW_VISUALIZATION: gdk_window_get_pointer(NULL, &x, &y, &modmask); ui_manager_popup_menu_show(GTK_MENU(mainwin_visualization_menu), x, y, 1, GDK_CURRENT_TIME); break; case MENUROW_NONE: break; } mainwin_release_info_text(); } void run_no_output_device_dialog(gpointer hook_data, gpointer user_data) { const gchar *markup = N_("<b><big>Couldn't open audio.</big></b>\n\n" "Please check that:\n" "1. You have the correct output plugin selected.\n" "2. No other programs is blocking the soundcard.\n" "3. Your soundcard is configured properly.\n"); GDK_THREADS_ENTER(); GtkWidget *dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(mainwin), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _(markup)); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); GDK_THREADS_LEAVE(); } void read_volume(gint when) { static gint pvl = 0, pvr = 0; static gint times = VOLSET_DISP_TIMES; static gboolean changing = FALSE; gint vl, vr, b, v; input_get_volume(&vl, &vr); switch (when) { case VOLSET_STARTUP: vl = CLAMP(vl, 0, 100); vr = CLAMP(vr, 0, 100); pvl = vl; pvr = vr; v = MAX(vl, vr); if (vl > vr) b = (gint) rint(((gdouble) vr / vl) * 100) - 100; else if (vl < vr) b = 100 - (gint) rint(((gdouble) vl / vr) * 100); else b = 0; balance = b; mainwin_set_volume_slider(v); equalizerwin_set_volume_slider(v); mainwin_set_balance_slider(b); equalizerwin_set_balance_slider(b); return; case VOLSET_UPDATE: if (vl == -1 || vr == -1) return; if (setting_volume) { pvl = vl; pvr = vr; return; } if (pvr == vr && pvl == vl && changing) { if (times < VOLSET_DISP_TIMES) times++; else { mainwin_release_info_text(); changing = FALSE; } } else if (pvr != vr || pvl != vl) { gchar *tmp; v = MAX(vl, vr); if (vl > vr) b = (gint) rint(((gdouble) vr / vl) * 100) - 100; else if (vl < vr) b = 100 - (gint) rint(((gdouble) vl / vr) * 100); else b = 0; if (MAX(vl, vr) != MAX(pvl, pvr)) tmp = g_strdup_printf(_("VOLUME: %d%%"), v); else { if (vl > vr) { tmp = g_strdup_printf(_("BALANCE: %d%% LEFT"), -b); } else if (vr == vl) tmp = g_strdup_printf(_("BALANCE: CENTER")); else { /* (vl < vr) */ tmp = g_strdup_printf(_("BALANCE: %d%% RIGHT"), b); } } mainwin_lock_info_text(tmp); g_free(tmp); pvr = vr; pvl = vl; times = 0; changing = TRUE; mainwin_set_volume_slider(v); equalizerwin_set_volume_slider(v); /* Don't change the balance slider if the volume has been * set to zero. The balance can be anything, and our best * guess is what is was before. */ if (v > 0) { balance = b; mainwin_set_balance_slider(b); equalizerwin_set_balance_slider(b); } } break; case VOLUME_ADJUSTED: pvl = vl; pvr = vr; break; case VOLUME_SET: times = 0; changing = TRUE; pvl = vl; pvr = vr; break; } } /* TODO: HAL! */ gboolean can_play_cd(void) { GList *ilist; for (ilist = get_input_list(); ilist; ilist = g_list_next(ilist)) { InputPlugin *ip = INPUT_PLUGIN(ilist->data); if (!g_ascii_strcasecmp(g_basename(ip->filename), PLUGIN_FILENAME("cdaudio"))) { return TRUE; } } return FALSE; } static void set_timer_mode(TimerMode mode) { if (mode == TIMER_ELAPSED) check_set(radioaction_group_viewtime, "view time elapsed", TRUE); else check_set(radioaction_group_viewtime, "view time remaining", TRUE); } static void set_timer_mode_menu_cb(TimerMode mode) { cfg.timer_mode = mode; } gboolean change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event) { if (event->button == 1) { change_timer_mode(); } else if (event->button == 3) return FALSE; return TRUE; } void change_timer_mode(void) { if (cfg.timer_mode == TIMER_ELAPSED) set_timer_mode(TIMER_REMAINING); else set_timer_mode(TIMER_ELAPSED); if (playback_get_playing()) mainwin_update_song_info(); } static void mainwin_playlist_prev(void) { playlist_prev(playlist_get_active()); } static void mainwin_playlist_next(void) { playlist_next(playlist_get_active()); } void mainwin_setup_menus(void) { set_timer_mode(cfg.timer_mode); /* View menu */ check_set(toggleaction_group_others, "view always on top", cfg.always_on_top); check_set(toggleaction_group_others, "view put on all workspaces", cfg.sticky); check_set(toggleaction_group_others, "roll up player", cfg.player_shaded); check_set(toggleaction_group_others, "roll up playlist editor", cfg.playlist_shaded); check_set(toggleaction_group_others, "roll up equalizer", cfg.equalizer_shaded); check_set(toggleaction_group_others, "view easy move", cfg.easy_move); check_set(toggleaction_group_others, "view doublesize", cfg.doublesize); /* Songname menu */ check_set(toggleaction_group_others, "autoscroll songname", cfg.autoscroll); check_set(toggleaction_group_others, "stop after current song", cfg.stopaftersong); /* Playback menu */ check_set(toggleaction_group_others, "playback repeat", cfg.repeat); check_set(toggleaction_group_others, "playback shuffle", cfg.shuffle); check_set(toggleaction_group_others, "playback no playlist advance", cfg.no_playlist_advance); /* Visualization menu */ switch ( cfg.vis_type ) { case VIS_ANALYZER: check_set(radioaction_group_vismode, "vismode analyzer", TRUE); break; case VIS_SCOPE: check_set(radioaction_group_vismode, "vismode scope", TRUE); break; case VIS_VOICEPRINT: check_set(radioaction_group_vismode, "vismode voiceprint", TRUE); break; case VIS_OFF: default: check_set(radioaction_group_vismode, "vismode off", TRUE); break; } switch ( cfg.analyzer_mode ) { case ANALYZER_FIRE: check_set(radioaction_group_anamode, "anamode fire", TRUE); break; case ANALYZER_VLINES: check_set(radioaction_group_anamode, "anamode vertical lines", TRUE); break; case ANALYZER_NORMAL: default: check_set(radioaction_group_anamode, "anamode normal", TRUE); break; } switch ( cfg.analyzer_type ) { case ANALYZER_BARS: check_set(radioaction_group_anatype, "anatype bars", TRUE); break; case ANALYZER_LINES: default: check_set(radioaction_group_anatype, "anatype lines", TRUE); break; } check_set(toggleaction_group_others, "anamode peaks", cfg.analyzer_peaks ); switch ( cfg.scope_mode ) { case SCOPE_LINE: check_set(radioaction_group_scomode, "scomode line", TRUE); break; case SCOPE_SOLID: check_set(radioaction_group_scomode, "scomode solid", TRUE); break; case SCOPE_DOT: default: check_set(radioaction_group_scomode, "scomode dot", TRUE); break; } switch ( cfg.voiceprint_mode ) { case VOICEPRINT_FIRE: check_set(radioaction_group_vprmode, "vprmode fire", TRUE); break; case VOICEPRINT_ICE: check_set(radioaction_group_vprmode, "vprmode ice", TRUE); break; case VOICEPRINT_NORMAL: default: check_set(radioaction_group_vprmode, "vprmode normal", TRUE); break; } switch ( cfg.vu_mode ) { case VU_SMOOTH: check_set(radioaction_group_wshmode, "wshmode smooth", TRUE); break; case VU_NORMAL: default: check_set(radioaction_group_wshmode, "wshmode normal", TRUE); break; } switch ( cfg.vis_refresh ) { case REFRESH_HALF: check_set(radioaction_group_refrate, "refrate half", TRUE); break; case REFRESH_QUARTER: check_set(radioaction_group_refrate, "refrate quarter", TRUE); break; case REFRESH_EIGTH: check_set(radioaction_group_refrate, "refrate eighth", TRUE); break; case REFRESH_FULL: default: check_set(radioaction_group_refrate, "refrate full", TRUE); break; } switch ( cfg.analyzer_falloff ) { case FALLOFF_SLOW: check_set(radioaction_group_anafoff, "anafoff slow", TRUE); break; case FALLOFF_MEDIUM: check_set(radioaction_group_anafoff, "anafoff medium", TRUE); break; case FALLOFF_FAST: check_set(radioaction_group_anafoff, "anafoff fast", TRUE); break; case FALLOFF_FASTEST: check_set(radioaction_group_anafoff, "anafoff fastest", TRUE); break; case FALLOFF_SLOWEST: default: check_set(radioaction_group_anafoff, "anafoff slowest", TRUE); break; } switch ( cfg.peaks_falloff ) { case FALLOFF_SLOW: check_set(radioaction_group_peafoff, "peafoff slow", TRUE); break; case FALLOFF_MEDIUM: check_set(radioaction_group_peafoff, "peafoff medium", TRUE); break; case FALLOFF_FAST: check_set(radioaction_group_peafoff, "peafoff fast", TRUE); break; case FALLOFF_FASTEST: check_set(radioaction_group_peafoff, "peafoff fastest", TRUE); break; case FALLOFF_SLOWEST: default: check_set(radioaction_group_peafoff, "peafoff slowest", TRUE); break; } } static void mainwin_info_double_clicked_cb(void) { playlist_fileinfo_current(playlist_get_active()); } static void mainwin_info_right_clicked_cb(void) { gint x, y; gdk_window_get_pointer(NULL, &x, &y, NULL); ui_manager_popup_menu_show(GTK_MENU(mainwin_songname_menu), x, y, 3, GDK_CURRENT_TIME); } static void mainwin_create_widgets(void) { mainwin_menubtn = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_menubtn, SKINNED_WINDOW(mainwin)->fixed, 6, 3, 9, 9, 0, 0, 0, 9, SKIN_TITLEBAR); g_signal_connect(mainwin_menubtn, "clicked", mainwin_menubtn_cb, NULL ); mainwin_minimize = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_minimize, SKINNED_WINDOW(mainwin)->fixed, 244, 3, 9, 9, 9, 0, 9, 9, SKIN_TITLEBAR); g_signal_connect(mainwin_minimize, "clicked", mainwin_minimize_cb, NULL ); mainwin_shade = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_shade, SKINNED_WINDOW(mainwin)->fixed, 254, 3, 9, 9, 0, cfg.player_shaded ? 27 : 18, 9, cfg.player_shaded ? 27 : 18, SKIN_TITLEBAR); g_signal_connect(mainwin_shade, "clicked", mainwin_shade_toggle, NULL ); mainwin_close = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_close, SKINNED_WINDOW(mainwin)->fixed, 264, 3, 9, 9, 18, 0, 18, 9, SKIN_TITLEBAR); g_signal_connect(mainwin_close, "clicked", mainwin_quit_cb, NULL ); mainwin_rew = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_rew, SKINNED_WINDOW(mainwin)->fixed, 16, 88, 23, 18, 0, 0, 0, 18, SKIN_CBUTTONS); g_signal_connect(mainwin_rew, "pressed", mainwin_rev_pushed, NULL); g_signal_connect(mainwin_rew, "released", mainwin_rev_release, NULL); mainwin_fwd = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_fwd, SKINNED_WINDOW(mainwin)->fixed, 108, 88, 22, 18, 92, 0, 92, 18, SKIN_CBUTTONS); g_signal_connect(mainwin_fwd, "pressed", mainwin_fwd_pushed, NULL); g_signal_connect(mainwin_fwd, "released", mainwin_fwd_release, NULL); mainwin_play = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_play, SKINNED_WINDOW(mainwin)->fixed, 39, 88, 23, 18, 23, 0, 23, 18, SKIN_CBUTTONS); g_signal_connect(mainwin_play, "clicked", mainwin_play_pushed, NULL ); mainwin_pause = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_pause, SKINNED_WINDOW(mainwin)->fixed, 62, 88, 23, 18, 46, 0, 46, 18, SKIN_CBUTTONS); g_signal_connect(mainwin_pause, "clicked", playback_pause, NULL ); mainwin_stop = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_stop, SKINNED_WINDOW(mainwin)->fixed, 85, 88, 23, 18, 69, 0, 69, 18, SKIN_CBUTTONS); g_signal_connect(mainwin_stop, "clicked", mainwin_stop_pushed, NULL ); mainwin_eject = ui_skinned_button_new(); ui_skinned_push_button_setup(mainwin_eject, SKINNED_WINDOW(mainwin)->fixed, 136, 89, 22, 16, 114, 0, 114, 16, SKIN_CBUTTONS); g_signal_connect(mainwin_eject, "clicked", mainwin_eject_pushed, NULL); mainwin_srew = ui_skinned_button_new(); ui_skinned_small_button_setup(mainwin_srew, SKINNED_WINDOW(mainwin)->fixed, 169, 4, 8, 7); g_signal_connect(mainwin_srew, "clicked", mainwin_playlist_prev, NULL); mainwin_splay = ui_skinned_button_new(); ui_skinned_small_button_setup(mainwin_splay, SKINNED_WINDOW(mainwin)->fixed, 177, 4, 10, 7); g_signal_connect(mainwin_splay, "clicked", mainwin_play_pushed, NULL); mainwin_spause = ui_skinned_button_new(); ui_skinned_small_button_setup(mainwin_spause, SKINNED_WINDOW(mainwin)->fixed, 187, 4, 10, 7); g_signal_connect(mainwin_spause, "clicked", playback_pause, NULL); mainwin_sstop = ui_skinned_button_new(); ui_skinned_small_button_setup(mainwin_sstop, SKINNED_WINDOW(mainwin)->fixed, 197, 4, 9, 7); g_signal_connect(mainwin_sstop, "clicked", mainwin_stop_pushed, NULL); mainwin_sfwd = ui_skinned_button_new(); ui_skinned_small_button_setup(mainwin_sfwd, SKINNED_WINDOW(mainwin)->fixed, 206, 4, 8, 7); g_signal_connect(mainwin_sfwd, "clicked", mainwin_playlist_next, NULL); mainwin_seject = ui_skinned_button_new(); ui_skinned_small_button_setup(mainwin_seject, SKINNED_WINDOW(mainwin)->fixed, 216, 4, 9, 7); g_signal_connect(mainwin_seject, "clicked", mainwin_eject_pushed, NULL); mainwin_shuffle = ui_skinned_button_new(); ui_skinned_toggle_button_setup(mainwin_shuffle, SKINNED_WINDOW(mainwin)->fixed, 164, 89, 46, 15, 28, 0, 28, 15, 28, 30, 28, 45, SKIN_SHUFREP); g_signal_connect(mainwin_shuffle, "clicked", mainwin_shuffle_pushed_cb, NULL); mainwin_repeat = ui_skinned_button_new(); ui_skinned_toggle_button_setup(mainwin_repeat, SKINNED_WINDOW(mainwin)->fixed, 210, 89, 28, 15, 0, 0, 0, 15, 0, 30, 0, 45, SKIN_SHUFREP); g_signal_connect(mainwin_repeat, "clicked", mainwin_repeat_pushed_cb, NULL); mainwin_eq = ui_skinned_button_new(); ui_skinned_toggle_button_setup(mainwin_eq, SKINNED_WINDOW(mainwin)->fixed, 219, 58, 23, 12, 0, 61, 46, 61, 0, 73, 46, 73, SKIN_SHUFREP); g_signal_connect(mainwin_eq, "clicked", mainwin_equalizer_pushed_cb, NULL); UI_SKINNED_BUTTON(mainwin_eq)->inside = cfg.equalizer_visible; mainwin_pl = ui_skinned_button_new(); ui_skinned_toggle_button_setup(mainwin_pl, SKINNED_WINDOW(mainwin)->fixed, 242, 58, 23, 12, 23, 61, 69, 61, 23, 73, 69, 73, SKIN_SHUFREP); g_signal_connect(mainwin_pl, "clicked", mainwin_playlist_pushed_cb, NULL); UI_SKINNED_BUTTON(mainwin_pl)->inside = cfg.playlist_visible; mainwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 112, 27, 153, 1, SKIN_TEXT); ui_skinned_textbox_set_scroll(mainwin_info, cfg.autoscroll); ui_skinned_textbox_set_xfont(mainwin_info, cfg.mainwin_use_xfont, cfg.mainwin_font); g_signal_connect(mainwin_info, "double-clicked", mainwin_info_double_clicked_cb, NULL); g_signal_connect(mainwin_info, "right-clicked", mainwin_info_right_clicked_cb, NULL); mainwin_othertext = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 112, 43, 153, 1, SKIN_TEXT); mainwin_rate_text = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 111, 43, 15, 0, SKIN_TEXT); mainwin_freq_text = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 156, 43, 10, 0, SKIN_TEXT); mainwin_menurow = ui_skinned_menurow_new(SKINNED_WINDOW(mainwin)->fixed, 10, 22, 304, 0, 304, 44, SKIN_TITLEBAR); g_signal_connect(mainwin_menurow, "change", G_CALLBACK(mainwin_mr_change), NULL); g_signal_connect(mainwin_menurow, "release", G_CALLBACK(mainwin_mr_release), NULL); mainwin_volume = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 107, 57, 68, 13, 15, 422, 0, 422, 14, 11, 15, 0, 0, 51, mainwin_volume_frame_cb, SKIN_VOLUME); g_signal_connect(mainwin_volume, "motion", G_CALLBACK(mainwin_volume_motion_cb), NULL); g_signal_connect(mainwin_volume, "release", G_CALLBACK(mainwin_volume_release_cb), NULL); mainwin_balance = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 177, 57, 38, 13, 15, 422, 0, 422, 14, 11, 15, 9, 0, 24, mainwin_balance_frame_cb, SKIN_BALANCE); g_signal_connect(mainwin_balance, "motion", G_CALLBACK(mainwin_balance_motion_cb), NULL); g_signal_connect(mainwin_balance, "release", G_CALLBACK(mainwin_balance_release_cb), NULL); mainwin_monostereo = ui_skinned_monostereo_new(SKINNED_WINDOW(mainwin)->fixed, 212, 41, SKIN_MONOSTEREO); mainwin_playstatus = ui_skinned_playstatus_new(SKINNED_WINDOW(mainwin)->fixed, 24, 28); mainwin_minus_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 36, 26, SKIN_NUMBERS); g_signal_connect(mainwin_minus_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); mainwin_10min_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 48, 26, SKIN_NUMBERS); g_signal_connect(mainwin_10min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); mainwin_min_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 60, 26, SKIN_NUMBERS); g_signal_connect(mainwin_min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); mainwin_10sec_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 78, 26, SKIN_NUMBERS); g_signal_connect(mainwin_10sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); mainwin_sec_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 90, 26, SKIN_NUMBERS); g_signal_connect(mainwin_sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); mainwin_about = ui_skinned_button_new(); ui_skinned_small_button_setup(mainwin_about, SKINNED_WINDOW(mainwin)->fixed, 247, 83, 20, 25); g_signal_connect(mainwin_about, "clicked", show_about_window, NULL); mainwin_vis = ui_vis_new(SKINNED_WINDOW(mainwin)->fixed, 24, 43, 76); g_signal_connect(mainwin_vis, "button-press-event", G_CALLBACK(mainwin_vis_cb), NULL); mainwin_svis = ui_svis_new(SKINNED_WINDOW(mainwin)->fixed, 79, 5); g_signal_connect(mainwin_svis, "button-press-event", G_CALLBACK(mainwin_vis_cb), NULL); mainwin_position = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 16, 72, 248, 10, 248, 0, 278, 0, 29, 10, 10, 0, 0, 219, NULL, SKIN_POSBAR); g_signal_connect(mainwin_position, "motion", G_CALLBACK(mainwin_position_motion_cb), NULL); g_signal_connect(mainwin_position, "release", G_CALLBACK(mainwin_position_release_cb), NULL); mainwin_sposition = ui_skinned_horizontal_slider_new(SKINNED_WINDOW(mainwin)->fixed, 226, 4, 17, 7, 17, 36, 17, 36, 3, 7, 36, 0, 1, 13, mainwin_spos_frame_cb, SKIN_TITLEBAR); g_signal_connect(mainwin_sposition, "motion", G_CALLBACK(mainwin_spos_motion_cb), NULL); g_signal_connect(mainwin_sposition, "release", G_CALLBACK(mainwin_spos_release_cb), NULL); mainwin_stime_min = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 130, 4, 15, FALSE, SKIN_TEXT); g_signal_connect(mainwin_stime_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); mainwin_stime_sec = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 147, 4, 10, FALSE, SKIN_TEXT); g_signal_connect(mainwin_stime_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL); err = gtk_message_dialog_new(GTK_WINDOW(mainwin), GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Error in Audacious.")); gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); /* Dang well better set an error message or you'll see this */ gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(err), "Boo! Bad stuff! Booga Booga!"); hook_associate("playback audio error", (void *) mainwin_stop_pushed, NULL); hook_associate("playback audio error", (void *) run_no_output_device_dialog, NULL); } static void mainwin_create_window(void) { gint width, height; mainwin = ui_skinned_window_new("player"); gtk_window_set_title(GTK_WINDOW(mainwin), _("Audacious")); gtk_window_set_role(GTK_WINDOW(mainwin), "player"); gtk_window_set_resizable(GTK_WINDOW(mainwin), FALSE); width = cfg.player_shaded ? MAINWIN_SHADED_WIDTH : bmp_active_skin->properties.mainwin_width; height = cfg.player_shaded ? MAINWIN_SHADED_HEIGHT : bmp_active_skin->properties.mainwin_height; if (cfg.doublesize) { width *= 2; height *= 2; } gtk_widget_set_size_request(mainwin, width, height); if (cfg.player_x != -1 && cfg.save_window_position) gtk_window_move(GTK_WINDOW(mainwin), cfg.player_x, cfg.player_y); g_signal_connect(mainwin, "destroy", G_CALLBACK(mainwin_destroy), NULL); g_signal_connect(mainwin, "button_press_event", G_CALLBACK(mainwin_mouse_button_press), NULL); g_signal_connect(mainwin, "scroll_event", G_CALLBACK(mainwin_scrolled), NULL); g_signal_connect(mainwin, "button_release_event", G_CALLBACK(mainwin_mouse_button_release), NULL); bmp_drag_dest_set(mainwin); g_signal_connect(mainwin, "key_press_event", G_CALLBACK(mainwin_keypress), NULL); ui_main_evlistener_init(); } void mainwin_create(void) { mainwin_create_window(); gtk_window_add_accel_group( GTK_WINDOW(mainwin) , ui_manager_get_accel_group() ); mainwin_create_widgets(); } void mainwin_attach_idle_func(void) { mainwin_timeout_id = g_timeout_add(MAINWIN_UPDATE_INTERVAL, mainwin_idle_func, NULL); } gboolean mainwin_update_song_info(void) { gint time = playback_get_time(); gint length, t; gchar stime_prefix; if (!playback_get_playing()) return FALSE; if (ab_position_a != -1 && ab_position_b != -1 && time > ab_position_b) playback_seek(ab_position_a/1000); length = playlist_get_current_length(playlist_get_active()); playlistwin_set_time(time, length, cfg.timer_mode); if (cfg.timer_mode == TIMER_REMAINING) { if (length != -1) { ui_skinned_number_set_number(mainwin_minus_num, 11); t = length - time; stime_prefix = '-'; } else { ui_skinned_number_set_number(mainwin_minus_num, 10); t = time; stime_prefix = ' '; } } else { ui_skinned_number_set_number(mainwin_minus_num, 10); t = time; stime_prefix = ' '; } t /= 1000; /* Show the time in the format HH:MM when we have more than 100 * minutes. */ if (t >= 100 * 60) t /= 60; ui_skinned_number_set_number(mainwin_10min_num, t / 600); ui_skinned_number_set_number(mainwin_min_num, (t / 60) % 10); ui_skinned_number_set_number(mainwin_10sec_num, (t / 10) % 6); ui_skinned_number_set_number(mainwin_sec_num, t % 10); if (!UI_SKINNED_HORIZONTAL_SLIDER(mainwin_sposition)->pressed) { gchar *time_str; time_str = g_strdup_printf("%c%2.2d", stime_prefix, t / 60); ui_skinned_textbox_set_text(mainwin_stime_min, time_str); g_free(time_str); time_str = g_strdup_printf("%2.2d", t % 60); ui_skinned_textbox_set_text(mainwin_stime_sec, time_str); g_free(time_str); } time /= 1000; length /= 1000; if (length > 0) { if (time > length) { ui_skinned_horizontal_slider_set_position(mainwin_position, 219); ui_skinned_horizontal_slider_set_position(mainwin_sposition, 13); } /* update the slider position ONLY if there is not a seek in progress */ else if (seek_state == MAINWIN_SEEK_NIL) { ui_skinned_horizontal_slider_set_position(mainwin_position, (time * 219) / length); ui_skinned_horizontal_slider_set_position(mainwin_sposition, ((time * 12) / length) + 1); } } else { ui_skinned_horizontal_slider_set_position(mainwin_position, 0); ui_skinned_horizontal_slider_set_position(mainwin_sposition, 1); } return TRUE; } static gboolean mainwin_idle_func(gpointer data) { static gint count = 0; GDK_THREADS_ENTER(); if (!count) { read_volume(VOLSET_UPDATE); count = 10; } else count--; /* tristate buttons seek */ if ( seek_state != MAINWIN_SEEK_NIL ) { GTimeVal now_time; GTimeVal delta_time; gulong now_dur; g_get_current_time(&now_time); delta_time.tv_usec = now_time.tv_usec - cb_time.tv_usec; delta_time.tv_sec = now_time.tv_sec - cb_time.tv_sec; now_dur = labs((delta_time.tv_sec * 1000) + (glong) (delta_time.tv_usec / 1000)); if ( now_dur > TRISTATE_THRESHOLD ) { gint np; if (seek_state == MAINWIN_SEEK_REV) np = seek_initial_pos - labs((gulong)(now_dur/100)); /* seek back */ else np = seek_initial_pos + labs((gulong)(now_dur/100)); /* seek forward */ /* boundaries check */ if (np < 0 ) np = 0; else if ( np > 219 ) np = 219; ui_skinned_horizontal_slider_set_position( mainwin_position , np ); mainwin_position_motion_cb( mainwin_position, np ); } } GDK_THREADS_LEAVE(); /* if (seek_state == MAINWIN_SEEK_REV) playback_seek(CLAMP(playback_get_time() - 1000, 0, playlist_get_current_length()) / 1000); else if (seek_state == MAINWIN_SEEK_FWD) playback_seek(CLAMP(playback_get_time() + 1000, 0, playlist_get_current_length()) / 1000); */ return TRUE; } void audacious_menu_main_show( gint x , gint y , guint button , guint time ) { /* convenience function that shows the main popup menu wherever requested */ ui_manager_popup_menu_show( GTK_MENU(mainwin_general_menu), x , y , button , time ); return; } /* toggleactionentries actions */ void action_anamode_peaks( GtkToggleAction * action ) { cfg.analyzer_peaks = gtk_toggle_action_get_active( action ); } void action_autoscroll_songname( GtkToggleAction * action ) { mainwin_set_title_scroll(gtk_toggle_action_get_active(action)); playlistwin_set_sinfo_scroll(cfg.autoscroll); /* propagate scroll setting to playlistwin_sinfo */ } void action_playback_noplaylistadvance( GtkToggleAction * action ) { cfg.no_playlist_advance = gtk_toggle_action_get_active( action ); } void action_playback_repeat( GtkToggleAction * action ) { cfg.repeat = gtk_toggle_action_get_active( action ); UI_SKINNED_BUTTON(mainwin_repeat)->inside = cfg.repeat; gtk_widget_queue_draw(mainwin_repeat); } void action_playback_shuffle( GtkToggleAction * action ) { cfg.shuffle = gtk_toggle_action_get_active( action ); playlist_set_shuffle(cfg.shuffle); UI_SKINNED_BUTTON(mainwin_shuffle)->inside = cfg.shuffle; gtk_widget_queue_draw(mainwin_shuffle); } void action_stop_after_current_song( GtkToggleAction * action ) { cfg.stopaftersong = gtk_toggle_action_get_active( action ); } void action_view_always_on_top( GtkToggleAction * action ) { UI_SKINNED_MENUROW(mainwin_menurow)->always_selected = gtk_toggle_action_get_active( action ); cfg.always_on_top = UI_SKINNED_MENUROW(mainwin_menurow)->always_selected; gtk_widget_queue_draw(mainwin_menurow); hint_set_always(cfg.always_on_top); } void action_view_doublesize( GtkToggleAction * action ) { UI_SKINNED_MENUROW(mainwin_menurow)->doublesize_selected = gtk_toggle_action_get_active( action ); gtk_widget_queue_draw(mainwin_menurow); set_doublesize(UI_SKINNED_MENUROW(mainwin_menurow)->doublesize_selected); gdk_flush(); } void action_view_easymove( GtkToggleAction * action ) { cfg.easy_move = gtk_toggle_action_get_active( action ); } void action_view_on_all_workspaces( GtkToggleAction * action ) { cfg.sticky = gtk_toggle_action_get_active( action ); hint_set_sticky(cfg.sticky); } void action_roll_up_equalizer( GtkToggleAction * action ) { equalizerwin_set_shade_menu_cb(gtk_toggle_action_get_active(action)); } void action_roll_up_player( GtkToggleAction * action ) { mainwin_set_shade_menu_cb(gtk_toggle_action_get_active(action)); } void action_roll_up_playlist_editor( GtkToggleAction * action ) { playlistwin_set_shade(gtk_toggle_action_get_active(action)); } void action_show_equalizer( GtkToggleAction * action ) { if (gtk_toggle_action_get_active(action)) equalizerwin_real_show(); else equalizerwin_real_hide(); } void action_show_playlist_editor( GtkToggleAction * action ) { if (gtk_toggle_action_get_active(action)) playlistwin_show(); else playlistwin_hide(); } void action_show_player( GtkToggleAction * action ) { mainwin_show(gtk_toggle_action_get_active(action)); } /* radioactionentries actions (one callback for each radio group) */ void action_anafoff( GtkAction *action, GtkRadioAction *current ) { mainwin_vis_set_afalloff(gtk_radio_action_get_current_value(current)); } void action_anamode( GtkAction *action, GtkRadioAction *current ) { mainwin_vis_set_analyzer_mode(gtk_radio_action_get_current_value(current)); } void action_anatype( GtkAction *action, GtkRadioAction *current ) { mainwin_vis_set_analyzer_type(gtk_radio_action_get_current_value(current)); } void action_peafoff( GtkAction *action, GtkRadioAction *current ) { mainwin_vis_set_pfalloff(gtk_radio_action_get_current_value(current)); } void action_refrate( GtkAction *action, GtkRadioAction *current ) { mainwin_vis_set_refresh(gtk_radio_action_get_current_value(current)); } void action_scomode( GtkAction *action, GtkRadioAction *current ) { cfg.scope_mode = gtk_radio_action_get_current_value(current); } void action_vismode( GtkAction *action, GtkRadioAction *current ) { mainwin_vis_set_type_menu_cb(gtk_radio_action_get_current_value(current)); } void action_vprmode( GtkAction *action, GtkRadioAction *current ) { cfg.voiceprint_mode = gtk_radio_action_get_current_value(current); } void action_wshmode( GtkAction *action, GtkRadioAction *current ) { cfg.vu_mode = gtk_radio_action_get_current_value(current); } void action_viewtime( GtkAction *action, GtkRadioAction *current ) { set_timer_mode_menu_cb(gtk_radio_action_get_current_value(current)); } /* actionentries actions */ void action_about_audacious( void ) { show_about_window(); } void action_play_file( void ) { run_filebrowser(PLAY_BUTTON); } void action_play_location( void ) { mainwin_show_add_url_window(); } void action_ab_set( void ) { Playlist *playlist = playlist_get_active(); if (playlist_get_current_length(playlist) != -1) { if (ab_position_a == -1) { ab_position_a = playback_get_time(); ab_position_b = -1; mainwin_lock_info_text("LOOP-POINT A POSITION SET."); } else if (ab_position_b == -1) { int time = playback_get_time(); if (time > ab_position_a) ab_position_b = time; mainwin_release_info_text(); } else { ab_position_a = playback_get_time(); ab_position_b = -1; mainwin_lock_info_text("LOOP-POINT A POSITION RESET."); } } } void action_ab_clear( void ) { Playlist *playlist = playlist_get_active(); if (playlist_get_current_length(playlist) != -1) { ab_position_a = ab_position_b = -1; mainwin_release_info_text(); } } void action_current_track_info( void ) { playlist_fileinfo_current(playlist_get_active()); } void action_jump_to_file( void ) { ui_jump_to_track(); } void action_jump_to_playlist_start( void ) { Playlist *playlist = playlist_get_active(); playlist_set_position(playlist, 0); } void action_jump_to_time( void ) { mainwin_jump_to_time(); } void action_playback_next( void ) { Playlist *playlist = playlist_get_active(); playlist_next(playlist); } void action_playback_previous( void ) { Playlist *playlist = playlist_get_active(); playlist_prev(playlist); } void action_playback_play( void ) { mainwin_play_pushed(); } void action_playback_pause( void ) { playback_pause(); } void action_playback_stop( void ) { mainwin_stop_pushed(); } void action_preferences( void ) { show_prefs_window(); } void action_quit( void ) { mainwin_quit_cb(); }