summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c317
1 files changed, 182 insertions, 135 deletions
diff --git a/main.c b/main.c
index c5c06875..466126df 100644
--- a/main.c
+++ b/main.c
@@ -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);
}