Code

screen_song: fix memory leak
[ncmpc.git] / src / screen_song.c
index 6d3a0342a7c592eed21b0083e05915592db900e9..d7b6d2c51d5b4feb7e52be03d6d39f67bb838064 100644 (file)
@@ -1,5 +1,5 @@
 /* ncmpc (Ncurses MPD Client)
- * (c) 2004-2010 The Music Player Daemon Project
+ * (c) 2004-2017 The Music Player Daemon Project
  * Project homepage: http://musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -25,7 +25,7 @@
 #include "i18n.h"
 #include "screen.h"
 #include "charset.h"
-#include "utils.h"
+#include "time_format.h"
 #include "mpdclient.h"
 
 #include <mpd/client.h>
@@ -38,6 +38,7 @@ enum {
        LABEL_LENGTH = MPD_TAG_COUNT,
        LABEL_PATH,
        LABEL_BITRATE,
+       LABEL_FORMAT,
        LABEL_POSITION,
 };
 
@@ -56,6 +57,7 @@ static const char *const tag_labels[] = {
        [MPD_TAG_COMMENT] = N_("Comment"),
        [LABEL_PATH] = N_("Path"),
        [LABEL_BITRATE] = N_("Bitrate"),
+       [LABEL_FORMAT] = N_("Format"),
 };
 
 static unsigned max_tag_label_width;
@@ -110,19 +112,6 @@ screen_song_clear(void)
        }
 }
 
-static void
-screen_song_paint(void);
-
-/**
- * Repaint and update the screen.
- */
-static void
-screen_song_repaint(void)
-{
-       screen_song_paint();
-       wrefresh(lw->w);
-}
-
 static const char *
 screen_song_list_callback(unsigned idx, gcc_unused void *data)
 {
@@ -133,7 +122,7 @@ screen_song_list_callback(unsigned idx, gcc_unused void *data)
 
 
 static void
-screen_song_init(WINDOW *w, int cols, int rows)
+screen_song_init(WINDOW *w, unsigned cols, unsigned rows)
 {
        for (unsigned i = 0; i < G_N_ELEMENTS(tag_labels); ++i) {
                if (tag_labels[i] != NULL) {
@@ -171,7 +160,7 @@ screen_song_exit(void)
 }
 
 static void
-screen_song_resize(int cols, int rows)
+screen_song_resize(unsigned cols, unsigned rows)
 {
        list_window_resize(lw, cols, rows);
 }
@@ -224,9 +213,12 @@ screen_song_append(const char *label, const char *value, unsigned label_col)
 
                char *p = g_strdup(value_iter);
                unsigned width = utf8_cut_width(p, value_col);
-               if (width == 0)
+               if (width == 0) {
                        /* not enough room for anything - bail out */
+                       g_free(entry);
+                       g_free(p);
                        break;
+               }
 
                *entry_iter = 0;
 
@@ -255,7 +247,7 @@ screen_song_append_tag(const struct mpd_song *song, enum mpd_tag_type tag)
 }
 
 static void
-screen_song_add_song(const struct mpd_song *song, const struct mpdclient *c)
+screen_song_add_song(const struct mpd_song *song)
 {
        assert(song != NULL);
 
@@ -312,15 +304,6 @@ screen_song_add_song(const struct mpd_song *song, const struct mpdclient *c)
 
        screen_song_append(_(tag_labels[LABEL_PATH]), mpd_song_get_uri(song),
                           max_tag_label_width);
-       if (mpdclient_is_playing(c) && c->song != NULL &&
-           strcmp(mpd_song_get_uri(c->song), mpd_song_get_uri(song)) == 0 &&
-           mpd_status_get_kbit_rate(c->status)) {
-               char buf[16];
-               g_snprintf(buf, sizeof(buf), _("%d kbps"),
-                          mpd_status_get_kbit_rate(c->status));
-               screen_song_append(_(tag_labels[LABEL_BITRATE]), buf,
-                                  max_tag_label_width);
-       }
 }
 
 static void
@@ -372,6 +355,41 @@ screen_song_add_stats(struct mpd_connection *connection)
        return true;
 }
 
+static void
+audio_format_to_string(char *buffer, size_t size,
+                      const struct mpd_audio_format *format)
+{
+#if LIBMPDCLIENT_CHECK_VERSION(2,10,0)
+       if (format->bits == MPD_SAMPLE_FORMAT_FLOAT) {
+               g_snprintf(buffer, size, "%u:f:%u",
+                          format->sample_rate,
+                          format->channels);
+               return;
+       }
+
+       if (format->bits == MPD_SAMPLE_FORMAT_DSD) {
+               if (format->sample_rate > 0 &&
+                   format->sample_rate % 44100 == 0) {
+                       /* use shortcuts such as "dsd64" which implies the
+                          sample rate */
+                       g_snprintf(buffer, size, "dsd%u:%u",
+                                  format->sample_rate * 8 / 44100,
+                                  format->channels);
+                       return;
+               }
+
+               g_snprintf(buffer, size, "%u:dsd:%u",
+                          format->sample_rate,
+                          format->channels);
+               return;
+       }
+#endif
+
+       g_snprintf(buffer, size, "%u:%u:%u",
+                  format->sample_rate, format->bits,
+                  format->channels);
+}
+
 static void
 screen_song_update(struct mpdclient *c)
 {
@@ -393,7 +411,7 @@ screen_song_update(struct mpdclient *c)
                                mpd_song_get_uri(c->song)) != 0 ||
                         !mpdclient_is_playing(c))) {
                g_ptr_array_add(current.lines, g_strdup(_("Selected song")) );
-               screen_song_add_song(current.selected_song, c);
+               screen_song_add_song(current.selected_song);
                g_ptr_array_add(current.lines, g_strdup("\0"));
        }
 
@@ -403,7 +421,25 @@ screen_song_update(struct mpdclient *c)
                }
                current.played_song = mpd_song_dup(c->song);
                g_ptr_array_add(current.lines, g_strdup(_("Currently playing song")));
-               screen_song_add_song(current.played_song, c);
+               screen_song_add_song(current.played_song);
+
+               if (mpd_status_get_kbit_rate(c->status) > 0) {
+                       char buf[16];
+                       g_snprintf(buf, sizeof(buf), _("%d kbps"),
+                                  mpd_status_get_kbit_rate(c->status));
+                       screen_song_append(_(tag_labels[LABEL_BITRATE]), buf,
+                                          max_tag_label_width);
+               }
+
+               const struct mpd_audio_format *format =
+                       mpd_status_get_audio_format(c->status);
+               if (format) {
+                       char buf[32];
+                       audio_format_to_string(buf, sizeof(buf), format);
+                       screen_song_append(_(tag_labels[LABEL_FORMAT]), buf,
+                                          max_tag_label_width);
+               }
+
                g_ptr_array_add(current.lines, g_strdup("\0"));
        }
 
@@ -413,14 +449,14 @@ screen_song_update(struct mpdclient *c)
                mpdclient_handle_error(c);
 
        list_window_set_length(lw, current.lines->len);
-       screen_song_repaint();
+       screen_song_paint();
 }
 
 static bool
 screen_song_cmd(struct mpdclient *c, command_t cmd)
 {
        if (list_window_scroll_cmd(lw, cmd)) {
-               screen_song_repaint();
+               screen_song_paint();
                return true;
        }
 
@@ -466,7 +502,7 @@ screen_song_cmd(struct mpdclient *c, command_t cmd)
        if (screen_find(lw, cmd, screen_song_list_callback, NULL)) {
                /* center the row */
                list_window_center(lw, lw->selected);
-               screen_song_repaint();
+               screen_song_paint();
                return true;
        }