diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 317 |
1 files changed, 182 insertions, 135 deletions
@@ -55,6 +55,7 @@ #include "volume.h" #include "plugins.h" #include "common.h" +#include "junklib.h" #ifndef PREFIX #error PREFIX must be defined @@ -261,6 +262,15 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi else if (!strcmp (parg, "--quit")) { messagepump_push (DB_EV_TERMINATE, 0, 0, 0); } + else if (!strcmp (parg, "--sm-client-id")) { + parg += strlen (parg); + parg++; + if (parg < pend) { + parg += strlen (parg); + parg++; + } + continue; + } else if (parg[0] != '-') { break; // unknown option is filename } @@ -454,7 +464,9 @@ server_update (void) { } close(s2); - free(buf); + if (buf) { + free(buf); + } } return 0; } @@ -513,97 +525,100 @@ player_mainloop (void) { uint32_t p2; int term = 0; while (messagepump_pop(&msg, &ctx, &p1, &p2) != -1) { - // broadcast to all plugins - DB_plugin_t **plugs = plug_get_list (); - for (int n = 0; plugs[n]; n++) { - if (plugs[n]->message) { - plugs[n]->message (msg, ctx, p1, p2); + if (!term) { // when term is set to 1 -- it means we can't handle events, but we still need to process them to avoid memleaks + // broadcast to all plugins + DB_plugin_t **plugs = plug_get_list (); + for (int n = 0; plugs[n]; n++) { + if (plugs[n]->message) { + plugs[n]->message (msg, ctx, p1, p2); + } } - } - DB_output_t *output = plug_get_output (); - switch (msg) { - case DB_EV_REINIT_SOUND: - plug_reinit_sound (); - streamer_reset (1); - conf_save (); - break; - case DB_EV_TERMINATE: - { - save_resume_state (); - + DB_output_t *output = plug_get_output (); + switch (msg) { + case DB_EV_REINIT_SOUND: + plug_reinit_sound (); + streamer_reset (1); + conf_save (); + break; + case DB_EV_TERMINATE: + { + save_resume_state (); + + pl_playqueue_clear (); + + // stop streaming and playback before unloading plugins + DB_output_t *output = plug_get_output (); + output->stop (); + streamer_free (); + output->free (); + term = 1; + } + break; + case DB_EV_PLAY_CURRENT: + if (p1) { + output->stop (); + pl_playqueue_clear (); + streamer_set_nextsong (0, 1); + } + else { + streamer_play_current_track (); + } + break; + case DB_EV_PLAY_NUM: + output->stop (); pl_playqueue_clear (); - - // stop streaming and playback before unloading plugins - DB_output_t *output = plug_get_output (); + streamer_set_nextsong (p1, 1); + if (pl_get_order () == PLAYBACK_ORDER_SHUFFLE_ALBUMS) { + int pl = streamer_get_current_playlist (); + playlist_t *plt = plt_get_for_idx (pl); + plt_init_shuffle_albums (plt, p1); + plt_unref (plt); + } + break; + case DB_EV_STOP: + streamer_set_nextsong (-2, 0); + break; + case DB_EV_NEXT: output->stop (); - streamer_free (); - output->free (); - term = 1; - } - break; - case DB_EV_PLAY_CURRENT: - if (p1) { + streamer_move_to_nextsong (1); + break; + case DB_EV_PREV: output->stop (); - pl_playqueue_clear (); - streamer_set_nextsong (0, 1); - } - else { - streamer_play_current_track (); - } - break; - case DB_EV_PLAY_NUM: - output->stop (); - pl_playqueue_clear (); - streamer_set_nextsong (p1, 1); - if (pl_get_order () == PLAYBACK_ORDER_SHUFFLE_ALBUMS) { - int pl = streamer_get_current_playlist (); - playlist_t *plt = plt_get_for_idx (pl); - plt_init_shuffle_albums (plt, p1); - plt_unref (plt); - } - break; - case DB_EV_STOP: - streamer_set_nextsong (-2, 0); - break; - case DB_EV_NEXT: - output->stop (); - streamer_move_to_nextsong (1); - break; - case DB_EV_PREV: - output->stop (); - streamer_move_to_prevsong (); - break; - case DB_EV_PAUSE: - if (output->state () != OUTPUT_STATE_PAUSED) { - output->pause (); - messagepump_push (DB_EV_PAUSED, 0, 1, 0); - } - break; - case DB_EV_TOGGLE_PAUSE: - if (output->state () == OUTPUT_STATE_PAUSED) { - output->unpause (); - messagepump_push (DB_EV_PAUSED, 0, 0, 0); - } - else { - output->pause (); - messagepump_push (DB_EV_PAUSED, 0, 1, 0); + streamer_move_to_prevsong (); + break; + case DB_EV_PAUSE: + if (output->state () != OUTPUT_STATE_PAUSED) { + output->pause (); + messagepump_push (DB_EV_PAUSED, 0, 1, 0); + } + break; + case DB_EV_TOGGLE_PAUSE: + if (output->state () == OUTPUT_STATE_PAUSED) { + output->unpause (); + messagepump_push (DB_EV_PAUSED, 0, 0, 0); + } + else { + output->pause (); + messagepump_push (DB_EV_PAUSED, 0, 1, 0); + } + break; + case DB_EV_PLAY_RANDOM: + output->stop (); + streamer_move_to_randomsong (); + break; + case DB_EV_PLAYLIST_REFRESH: + pl_save_current (); + messagepump_push (DB_EV_PLAYLISTCHANGED, 0, 0, 0); + break; + case DB_EV_CONFIGCHANGED: + conf_save (); + streamer_configchanged (); + junk_configchanged (); + break; + case DB_EV_SEEK: + streamer_set_seek (p1 / 1000.f); + break; } - break; - case DB_EV_PLAY_RANDOM: - output->stop (); - streamer_move_to_randomsong (); - break; - case DB_EV_PLAYLIST_REFRESH: - pl_save_current (); - messagepump_push (DB_EV_PLAYLISTCHANGED, 0, 0, 0); - break; - case DB_EV_CONFIGCHANGED: - conf_save (); - streamer_configchanged (); - break; - case DB_EV_SEEK: - streamer_set_seek (p1 / 1000.f); - break; } if (msg >= DB_EV_FIRST && ctx) { messagepump_event_free ((ddb_event_t *)ctx); @@ -661,6 +676,13 @@ restore_resume_state (void) { streamer_lock (); // need to hold streamer thread to make the resume operation atomic streamer_set_current_playlist (plt); streamer_set_nextsong (track, paused ? 2 : 3); + if (pl_get_order () == PLAYBACK_ORDER_SHUFFLE_ALBUMS) { + playlist_t *p = plt_get_for_idx (plt); + if (p) { + plt_init_shuffle_albums (p, track); + plt_unref (p); + } + } streamer_set_seek (pos); streamer_unlock (); } @@ -669,15 +691,44 @@ restore_resume_state (void) { int main (int argc, char *argv[]) { + int portable = 0; +#if STATICLINK + int staticlink = 1; +#else + int staticlink = 0; +#endif #if PORTABLE - strcpy (dbinstalldir, argv[0]); - char *e = dbinstalldir + strlen (dbinstalldir); - while (e >= dbinstalldir && *e != '/') { - e--; + portable = 1; + if (!realpath (argv[0], dbinstalldir)) { + strcpy (dbinstalldir, argv[0]); + } + char *e = strrchr (dbinstalldir, '/'); + if (e) { + *e = 0; + } + else { + fprintf (stderr, "couldn't determine install folder from path %s\n", argv[0]); + exit (-1); } - *e = 0; #else - strcpy (dbinstalldir, PREFIX); + if (!realpath (argv[0], dbinstalldir)) { + strcpy (dbinstalldir, argv[0]); + } + char *e = strrchr (dbinstalldir, '/'); + if (e) { + *e = 0; + struct stat st; + char checkpath[PATH_MAX]; + snprintf (checkpath, sizeof (checkpath), "%s/.ddb_portable", dbinstalldir); + if (!stat (checkpath, &st)) { + if (S_ISREG (st.st_mode)) { + portable = 1; + } + } + } + if (!portable) { + strcpy (dbinstalldir, PREFIX); + } #endif #ifdef __linux__ @@ -687,26 +738,18 @@ main (int argc, char *argv[]) { setlocale (LC_NUMERIC, "C"); #ifdef ENABLE_NLS // fprintf (stderr, "enabling gettext support: package=" PACKAGE ", dir=" LOCALEDIR "...\n"); -#if PORTABLE - char localedir[PATH_MAX]; - snprintf (localedir, sizeof (localedir), "%s/locale", dbinstalldir); - bindtextdomain (PACKAGE, localedir); -#else - bindtextdomain (PACKAGE, LOCALEDIR); -#endif + if (portable) { + char localedir[PATH_MAX]; + snprintf (localedir, sizeof (localedir), "%s/locale", dbinstalldir); + bindtextdomain (PACKAGE, localedir); + } + else { + bindtextdomain (PACKAGE, LOCALEDIR); + } bind_textdomain_codeset (PACKAGE, "UTF-8"); textdomain (PACKAGE); #endif - int staticlink = 0; - int portable = 0; -#if STATICLINK - staticlink = 1; -#endif -#if PORTABLE - portable = 1; -#endif - fprintf (stderr, "starting deadbeef " VERSION "%s%s\n", staticlink ? " [static]" : "", portable ? " [portable]" : ""); srand (time (NULL)); #ifdef __linux__ @@ -748,34 +791,35 @@ main (int argc, char *argv[]) { #endif -#if PORTABLE - if (snprintf (dbdocdir, sizeof (dbdocdir), "%s/doc", dbinstalldir) > sizeof (dbdocdir)) { - fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); - return -1; - } - if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/plugins", dbinstalldir) > sizeof (dbplugindir)) { - fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); - return -1; - } - if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/pixmaps", dbinstalldir) > sizeof (dbpixmapdir)) { - fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); - return -1; - } - mkdir (dbplugindir, 0755); -#else - if (snprintf (dbdocdir, sizeof (dbdocdir), "%s", DOCDIR) > sizeof (dbdocdir)) { - fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); - return -1; - } - if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/deadbeef", LIBDIR) > sizeof (dbplugindir)) { - fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); - return -1; + if (portable) { + if (snprintf (dbdocdir, sizeof (dbdocdir), "%s/doc", dbinstalldir) > sizeof (dbdocdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/plugins", dbinstalldir) > sizeof (dbplugindir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/pixmaps", dbinstalldir) > sizeof (dbpixmapdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + mkdir (dbplugindir, 0755); } - if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/share/deadbeef/pixmaps", PREFIX) > sizeof (dbpixmapdir)) { - fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); - return -1; + else { + if (snprintf (dbdocdir, sizeof (dbdocdir), "%s", DOCDIR) > sizeof (dbdocdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + if (snprintf (dbplugindir, sizeof (dbplugindir), "%s/deadbeef", LIBDIR) > sizeof (dbplugindir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } + if (snprintf (dbpixmapdir, sizeof (dbpixmapdir), "%s/share/deadbeef/pixmaps", PREFIX) > sizeof (dbpixmapdir)) { + fprintf (stderr, "fatal: too long install path %s\n", dbinstalldir); + return -1; + } } -#endif for (int i = 1; i < argc; i++) { // help, version and nowplaying are executed with any filter @@ -854,6 +898,9 @@ main (int argc, char *argv[]) { fprintf (stderr, "%s\n", out); } } + if (out) { + free (out); + } close (s); exit (0); } |