--- xmms-1.2.10.orig/libxmms/configfile.c 2003-05-19 23:22:07.000000000 +0200 +++ xmms-1.2.10/libxmms/configfile.c 2006-07-07 11:41:12.000000000 +0200 @@ -43,15 +43,15 @@ ConfigFile *xmms_cfg_new(void) return cfg; } -ConfigFile *xmms_cfg_open_file(gchar * filename) +static +ConfigFile *xmms_cfg_open_or_merge_file(ConfigFile *cfg, gchar * filename) { - ConfigFile *cfg; - FILE *file; char *buffer, **lines, *tmp; int i; struct stat stats; ConfigSection *section = NULL; + ConfigLine *line; g_return_val_if_fail(filename != NULL, FALSE); @@ -70,7 +70,9 @@ ConfigFile *xmms_cfg_open_file(gchar * f fclose(file); buffer[stats.st_size] = '\0'; - cfg = g_malloc0(sizeof (ConfigFile)); + if (!cfg) + cfg = g_malloc0(sizeof (ConfigFile)); + lines = g_strsplit(buffer, "\n", 0); g_free(buffer); i = 0; @@ -81,7 +83,9 @@ ConfigFile *xmms_cfg_open_file(gchar * f if ((tmp = strchr(lines[i], ']'))) { *tmp = '\0'; - section = xmms_cfg_create_section(cfg, &lines[i][1]); + section = xmms_cfg_find_section(cfg, &lines[i][1]); + if (!section) + section = xmms_cfg_create_section(cfg, &lines[i][1]); } } else if (lines[i][0] != '#' && section) @@ -90,7 +94,13 @@ ConfigFile *xmms_cfg_open_file(gchar * f { *tmp = '\0'; tmp++; - xmms_cfg_create_string(section, lines[i], tmp); + if ((line = xmms_cfg_find_string(section, lines[i]))) + { + g_free(line->value); + line->value = g_strchug(g_strchomp(g_strdup(tmp))); + } + else + xmms_cfg_create_string(section, lines[i], tmp); } } i++; @@ -99,6 +109,20 @@ ConfigFile *xmms_cfg_open_file(gchar * f return cfg; } +static gchar *custom_filename = NULL; +ConfigFile *xmms_cfg_open_file(gchar *filename) +{ + ConfigFile *cfg = xmms_cfg_open_or_merge_file(NULL, filename); + if (cfg && custom_filename) + xmms_cfg_open_or_merge_file(cfg, custom_filename); + return cfg; +} + +void xmms_cfg_set_custom_filename(gchar *filename) +{ + custom_filename = filename; +} + gchar * xmms_cfg_get_default_filename(void) { static char *filename = NULL; --- xmms-1.2.10.orig/libxmms/configfile.h 2006-07-06 16:07:55.000000000 +0200 +++ xmms-1.2.10/libxmms/configfile.h 2006-07-07 11:41:12.000000000 +0200 @@ -67,6 +67,8 @@ void xmms_cfg_write_double(ConfigFile * void xmms_cfg_remove_key(ConfigFile * cfg, gchar * section, gchar * key); +void xmms_cfg_set_custom_filename(gchar *filename); + #ifdef __cplusplus } #endif --- xmms-1.2.10.orig/xmms/controlsocket.c 2006-07-06 16:07:55.000000000 +0200 +++ xmms-1.2.10/xmms/controlsocket.c 2006-07-07 11:41:12.000000000 +0200 @@ -50,13 +50,18 @@ static pthread_cond_t start_cond = PTHRE gboolean setup_ctrlsocket(void) { + return setup_ctrlsocket_internal(-1); +} + +gboolean setup_ctrlsocket_internal(gint session_id) +{ struct sockaddr_un saddr; gboolean retval = FALSE; gint i; if ((ctrl_fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) { - for (i = 0;; i++) + for (i = ((session_id >= 0) ? session_id : 0); (session_id < 0 || i == session_id); i++) { saddr.sun_family = AF_UNIX; g_snprintf(saddr.sun_path, 108, "%s/xmms_%s.%d", @@ -72,10 +77,17 @@ gboolean setup_ctrlsocket(void) } else { + if (session_id >= 0 && session_id != i) + { + g_log(NULL, G_LOG_LEVEL_CRITICAL, + "setup_ctrlsocket(): Session %d already running!", session_id); + break; + } if (cfg.allow_multiple_instances) continue; break; } + if (bind(ctrl_fd, (struct sockaddr *) &saddr, sizeof (saddr)) != -1) { session_id = i; @@ -95,6 +107,7 @@ gboolean setup_ctrlsocket(void) break; } } + } else g_log(NULL, G_LOG_LEVEL_CRITICAL, --- xmms-1.2.10.orig/xmms/controlsocket.h 2006-07-06 16:07:55.000000000 +0200 +++ xmms-1.2.10/xmms/controlsocket.h 2006-07-07 11:41:12.000000000 +0200 @@ -23,6 +23,7 @@ #define XMMS_PROTOCOL_VERSION 1 gboolean setup_ctrlsocket(void); +gboolean setup_ctrlsocket_internal(gint session_id); void cleanup_ctrlsocket(void); void start_ctrlsocket(void); void check_ctrlsocket(void); --- xmms-1.2.10.orig/xmms/input.c 2006-07-06 16:07:55.000000000 +0200 +++ xmms-1.2.10/xmms/input.c 2006-07-07 11:41:12.000000000 +0200 @@ -286,6 +286,14 @@ void input_seek(int time) } } +gboolean input_stopped_for_restart = FALSE; /* crossfade */ +void input_stop_for_restart() /* crossfade */ +{ + input_stopped_for_restart = TRUE; + input_stop(); + input_stopped_for_restart = FALSE; +} + void input_stop(void) { if (ip_data->playing && get_current_input_plugin()) --- xmms-1.2.10.orig/xmms/input.h 2000-02-16 22:05:57.000000000 +0100 +++ xmms-1.2.10/xmms/input.h 2006-07-07 11:41:12.000000000 +0200 @@ -34,6 +34,7 @@ InputVisType input_get_vis_type(); gboolean input_check_file(gchar * filename); void input_play(char *filename); void input_stop(void); +void input_stop_for_restart(void); void input_pause(void); int input_get_time(void); void input_set_eq(int on, float preamp, float *bands); --- xmms-1.2.10.orig/xmms/main.c 2006-07-06 16:07:56.000000000 +0200 +++ xmms-1.2.10/xmms/main.c 2006-07-07 11:56:34.000000000 +0200 @@ -1,3 +1,4 @@ + /* XMMS - Cross-platform multimedia player * Copyright (C) 1998-2003 Peter Alm, Mikael Alm, Olle Hallnas, * Thomas Nilsson and 4Front Technologies @@ -1010,8 +1011,10 @@ void mainwin_shade_toggle(void) mainwin_set_shade(!cfg.player_shaded); } +gboolean is_quitting = FALSE; /* crossfade */ void mainwin_quit_cb(void) { + is_quitting = TRUE; /* crossfade */ input_stop(); gtk_widget_hide(equalizerwin); gtk_widget_hide(playlistwin); @@ -1691,7 +1694,8 @@ static void mainwin_jump_to_file_real_cb int *pos; if (get_input_playing()) - input_stop(); + input_stop_for_restart(); + pos = gtk_clist_get_row_data(clist, GPOINTER_TO_INT(clist->selection->data)); playlist_set_position(*pos); playlist_play(); @@ -3442,6 +3446,7 @@ static struct option long_options[] = { {"help", 0, NULL, 'h'}, {"session", 1, NULL, 'n'}, + {"force-session", 0, NULL, 'N' }, {"rew", 0, NULL, 'r'}, {"play", 0, NULL, 'p'}, {"pause", 0, NULL, 'u'}, @@ -3458,6 +3463,7 @@ static struct option long_options[] = {"version", 0, NULL, 'v'}, {"quit", 0, NULL, 'q'}, {"sm-client-id", 1, NULL, 'i'}, + {"config", 1, NULL, 'c'}, {0, 0, 0, 0} }; @@ -3469,9 +3475,15 @@ void display_usage(void) fprintf(stderr, "\n -h, --help "); /* I18N: -h, --help switch */ fprintf(stderr, _("Display this text and exit.")); + fprintf(stderr, "\n -c, --config "); + /* I18N: -c, --config switch */ + fprintf(stderr, _("Additional custom configuration file")); fprintf(stderr, "\n -n, --session "); - /* I18N: -n, --session switch */ + /* I18N: -n, --session option */ fprintf(stderr, _("Select XMMS session (Default: 0)")); + fprintf(stderr, "\n -N, --force-session "); + /* I18N: -N, -force-session switch */ + fprintf(stderr, _("Force XMMS session")); fprintf(stderr, "\n -r, --rew "); /* I18N: -r, --rew switch */ fprintf(stderr, _("Skip backwards in playlist")); @@ -3490,7 +3502,7 @@ void display_usage(void) fprintf(stderr, "\n -f, --fwd "); /* I18N: -f, --fwd switch */ fprintf(stderr, _("Skip forward in playlist")); - fprintf(stderr, "\n-j, --show-jump-box "); + fprintf(stderr, "\n -j, --show-jump-box "); /* -j, --show-jump-box switch */ fprintf(stderr, _("Display Jump to file dialog")); fprintf(stderr, "\n -e, --enqueue "); @@ -3534,6 +3546,7 @@ void display_usage(void) struct cmdlineopt { GList *filenames; int session; + gboolean force_session; gboolean play, stop, pause, fwd, rew, play_pause, show_jump_box; gboolean toggle_shuffle, toggle_repeat, toggle_advance; gboolean enqueue, queue, mainwin, remote, quit; @@ -3548,7 +3561,8 @@ void parse_cmd_line(int argc, char **arg memset(opt, 0, sizeof(struct cmdlineopt)); opt->session = -1; - while ((c = getopt_long(argc, argv, "hn:rpusfeQS::R::A::mi:vtqj", long_options, NULL)) != -1) + opt->force_session = FALSE; + while ((c = getopt_long(argc, argv, "hn:rpusfeQS::R::A::mi:vtqjNc", long_options, NULL)) != -1) { switch (c) { @@ -3558,6 +3572,12 @@ void parse_cmd_line(int argc, char **arg case 'n': opt->session = atoi(optarg); break; + case 'N': + opt->force_session = TRUE; + break; + case 'c': + xmms_cfg_set_custom_filename(g_strdup(optarg)); + break; case 'r': opt->rew = TRUE; break; @@ -3965,7 +3985,9 @@ int main(int argc, char **argv) } make_xmms_dir(); - if (options.session != -1 || !setup_ctrlsocket()) + if (options.force_session + ? !setup_ctrlsocket_internal(options.session) + : (options.session != -1 || !setup_ctrlsocket())) { handle_cmd_line_options(&options, TRUE); exit(0); --- xmms-1.2.10.orig/xmms/playlist.c 2006-07-06 16:07:56.000000000 +0200 +++ xmms-1.2.10/xmms/playlist.c 2006-07-07 12:01:36.000000000 +0200 @@ -40,7 +40,7 @@ extern SVis *mainwin_svis; static gboolean playlist_get_info_entry(PlaylistEntry *entry); static int playlist_sort_str_by_path_cmpfunc(gconstpointer a, gconstpointer b); static guint playlist_load_ins(char * filename, long pos); -static void playlist_load_ins_file(char *filename, char *playlist_name, long pos, char *title, int len); +static void playlist_load_ins_file(char *filename, char *playlist_name, long pos, char *title, int len, char *fade); static int __get_playlist_length(void); static void playlist_generate_shuffle_list(void); static void __playlist_generate_shuffle_list(void); @@ -79,9 +79,10 @@ void playlist_clear(void) { GList *node; PlaylistEntry *entry; - + + /* always assume that there is another song comming up */ if (get_input_playing()) - input_stop(); + input_stop_for_restart(); PL_LOCK(); if (playlist) @@ -90,10 +91,9 @@ void playlist_clear(void) while (node) { entry = node->data; - if (entry->filename) - g_free(entry->filename); - if (entry->title) - g_free(entry->title); + g_free(entry->filename); + g_free(entry->title); + g_free(entry->fade); g_free(entry); node = node->next; } @@ -143,7 +143,7 @@ void playlist_delete_node(GList *node, g if (get_input_playing()) { PL_UNLOCK(); - input_stop(); + input_stop_for_restart(); PL_LOCK(); *restart_playing = TRUE; } @@ -165,10 +165,9 @@ void playlist_delete_node(GList *node, g g_list_position(playlist, node)) *set_info_text = TRUE; - if (entry->filename) - g_free(entry->filename); - if (entry->title) - g_free(entry->title); + g_free(entry->filename); + g_free(entry->title); + g_free(entry->fade); shuffle_list = g_list_remove(shuffle_list, entry); playlist = g_list_remove_link(playlist, node); g_free(entry); @@ -276,15 +275,15 @@ void playlist_delete(gboolean crop) mainwin_set_info_text(); } -static void __playlist_ins_with_info(char *filename, long pos, char* title, int len) +static void __playlist_ins_with_info(char *filename, long pos, char* title, int len, char *fade) { PlaylistEntry *entry; entry = g_malloc0(sizeof (PlaylistEntry)); entry->filename = g_strdup(filename); - if (title) - entry->title = g_strdup(title); - entry->length = len; + entry->title = g_strdup(title); + entry->length = len; + entry->fade = g_strdup(fade); PL_LOCK(); playlist = g_list_insert(playlist, entry, pos); @@ -293,9 +292,9 @@ static void __playlist_ins_with_info(cha playlist_get_info_scan_active = TRUE; } -static void __playlist_ins(char * filename, long pos) +static void __playlist_ins(char *filename, long pos) { - __playlist_ins_with_info(filename, pos, NULL, -1); + __playlist_ins_with_info(filename, pos, NULL, -1, NULL); } static gboolean is_playlist_name(char *pathname) @@ -583,7 +582,7 @@ void playlist_play(void) } if (get_input_playing()) - input_stop(); + input_stop_for_restart(); vis_clear_data(mainwin_vis); vis_clear_data(playlistwin_vis); @@ -681,7 +680,7 @@ void playlist_next(void) { /* We need to stop before changing playlist_position */ PL_UNLOCK(); - input_stop(); + input_stop_for_restart(); PL_LOCK(); restart_playing = TRUE; } @@ -736,7 +735,7 @@ void playlist_prev(void) { /* We need to stop before changing playlist_position */ PL_UNLOCK(); - input_stop(); + input_stop_for_restart(); PL_LOCK(); restart_playing = TRUE; } @@ -887,7 +886,7 @@ void playlist_set_position(int pos) { /* We need to stop before changing playlist_position */ PL_UNLOCK(); - input_stop(); + input_stop_for_restart(); PL_LOCK(); restart_playing = TRUE; } @@ -914,11 +913,25 @@ void playlist_set_position(int pos) void playlist_eof_reached(void) { GList *plist_pos_list; - - input_stop(); + gboolean stop_for_restart = TRUE; PL_LOCK(); + + /* + * First, determine if we are going to play another song after + * this one and call input_stop() / input_stop_for_restart() + * accordingly. + */ plist_pos_list = find_playlist_position_list(); + if (!queued_list && !g_list_next(plist_pos_list) && !cfg.repeat) + stop_for_restart = FALSE; + + PL_UNLOCK(); + if (stop_for_restart) + input_stop_for_restart(); + else + input_stop(); + PL_LOCK(); if (cfg.no_playlist_advance) { @@ -1095,7 +1108,7 @@ gboolean playlist_load(char * filename) return playlist_load_ins(filename, -1); } -static void playlist_load_ins_file(char *filename, char *playlist_name, long pos, char *title, int len) +static void playlist_load_ins_file(char *filename, char *playlist_name, long pos, char *title, int len, char *fade) { char *temp, *path; @@ -1115,16 +1128,16 @@ static void playlist_load_ins_file(char *temp = '\0'; else { - __playlist_ins_with_info(filename, pos, title, len); + __playlist_ins_with_info(filename, pos, title, len, fade); return; } temp = g_strdup_printf("%s/%s", path, filename); - __playlist_ins_with_info(temp, pos, title, len); + __playlist_ins_with_info(temp, pos, title, len, fade); g_free(temp); g_free(path); } else - __playlist_ins_with_info(filename, pos, title, len); + __playlist_ins_with_info(filename, pos, title, len, fade); } static void parse_extm3u_info(char *info, char **title, int *length) @@ -1163,7 +1176,7 @@ static guint playlist_load_ins(char * fi guint entries = 0; int linelen = 1024; gboolean extm3u = FALSE; - char *ext_info = NULL, *ext_title = NULL; + char *ext_info = NULL, *ext_title = NULL, *ext_fade = NULL; int ext_len = -1; ext = strrchr(filename, '.'); @@ -1193,7 +1206,7 @@ static guint playlist_load_ins(char * fi if (line != NULL) { playlist_load_ins_file(line, filename, pos, - ext_title, -1); + ext_title, -1, NULL); entries++; if (pos >= 0) pos++; @@ -1242,6 +1255,13 @@ static guint playlist_load_ins(char * fi ext_info = g_strdup(line); continue; } + else if (extm3u && !strncmp(line, "#EXTFADE:", 9)) + { + if (ext_fade) + g_free(ext_fade); + ext_fade = g_strdup(line); + continue; + } if (line[0] == '#') { @@ -1261,11 +1281,14 @@ static guint playlist_load_ins(char * fi ext_info = NULL; } - playlist_load_ins_file(line, filename, pos, ext_title, ext_len); + playlist_load_ins_file(line, filename, pos, ext_title, ext_len, ext_fade); g_free(ext_title); ext_title = NULL; ext_len = -1; + + g_free(ext_fade); + ext_fade = NULL; entries++; if (pos >= 0) @@ -1409,6 +1432,32 @@ int playlist_get_songtime(int pos) return retval; } +char * playlist_get_fadeinfo(int pos) +{ + char *ret; + PlaylistEntry *entry; + GList *node; + + PL_LOCK(); + if (!playlist) + { + PL_UNLOCK(); + return NULL; + } + node = g_list_nth(playlist, pos); + if (!node) + { + PL_UNLOCK(); + return NULL; + } + entry = node->data; + + ret = g_strdup(entry->fade); + PL_UNLOCK(); + + return ret; +} + static int playlist_sort_by_title_cmpfunc(PlaylistEntry * a, PlaylistEntry * b) { char *a_title, *b_title; --- xmms-1.2.10.orig/xmms/playlist.h 2006-07-06 16:07:56.000000000 +0200 +++ xmms-1.2.10/xmms/playlist.h 2006-07-07 11:50:28.000000000 +0200 @@ -22,10 +22,11 @@ typedef struct { - gchar *filename; - gchar *title; - gint length; - gboolean selected; + gchar *filename; + gchar *title; + gint length; + gboolean selected; + gchar *fade; } PlaylistEntry;