internal rewrite of mpd support
authorPhil Sutter <phil@nwl.cc>
Thu, 18 Dec 2008 12:37:53 +0000 (13:37 +0100)
committerPhil Sutter <phil@nwl.cc>
Thu, 18 Dec 2008 12:40:21 +0000 (13:40 +0100)
Handle mpd internal information inside mpd.c. Use a refcounter to check
if the mpd-information can be freed (maybe useless). Remove the now
useless "full" flag of free_text_objects.

src/common.c
src/conky.c
src/conky.h
src/mpd.c
src/mpd.h

index aff0bcd..bbfffc0 100644 (file)
@@ -332,18 +332,7 @@ void update_stuff(void)
 
 #ifdef MPD
        if (NEED(INFO_MPD)) {
-               if (!info.mpd.timed_thread) {
-                       init_mpd_stats(&info.mpd);
-                       info.mpd.timed_thread = timed_thread_create(&update_mpd,
-                               (void *) &info.mpd, info.music_player_interval * 1000000);
-                       if (!info.mpd.timed_thread) {
-                               ERR("Failed to create MPD timed thread");
-                       }
-                       timed_thread_register(info.mpd.timed_thread, &info.mpd.timed_thread);
-                       if (timed_thread_run(info.mpd.timed_thread)) {
-                               ERR("Failed to run MPD timed thread");
-                       }
-               }
+               update_mpd();
        }
 #endif
 
index 1a7ebd7..b87c249 100644 (file)
@@ -1200,10 +1200,8 @@ static struct text_object *new_text_object_internal(void)
        return obj;
 }
 
-/*
- * call with full == 0 when freeing after 'internal' evaluation of objects
- */
-static void free_text_objects(struct text_object *root, char full)
+/* free the list of text objects root points to */
+static void free_text_objects(struct text_object *root)
 {
        struct text_object *obj;
 
@@ -1506,9 +1504,7 @@ static void free_text_objects(struct text_object *root, char full)
                        case OBJ_mpd_percent:
                        case OBJ_mpd_smart:
                        case OBJ_if_mpd_playing:
-                               if (full) {
-                                       free_mpd_vars(&info.mpd);
-                               }
+                               free_mpd();
                                break;
 #endif
 #ifdef MOC
@@ -1533,8 +1529,6 @@ static void free_text_objects(struct text_object *root, char full)
                free(obj);
        }
 #undef data
-       /* FIXME: below is surely useless */
-       if (full) {} // disable warning when MPD !defined
 }
 
 void scan_mixer_bar(const char *arg, int *a, int *w, int *h)
@@ -2872,102 +2866,51 @@ static struct text_object *construct_text_object(const char *s,
                        ERR("smapi_bat_bar needs an argument");
 #endif /* SMAPI */
 #ifdef MPD
-       END OBJ_THREAD(mpd_artist, INFO_MPD)
-               if (arg) {
-                       sscanf(arg, "%d", &obj->data.i);
-                       if (obj->data.i > 0) {
-                               obj->data.i++;
-                       } else {
-                               ERR("mpd_artist: invalid length argument");
-                               obj->data.i = 0;
-                       }
-               } else {
-                       obj->data.i = 0;
+#define mpd_set_maxlen(name) \
+               if (arg) { \
+                       int i; \
+                       sscanf(arg, "%d", &i); \
+                       if (i > 0) \
+                               obj->data.i = i + 1; \
+                       else \
+                               ERR(#name ": invalid length argument"); \
                }
+       END OBJ_THREAD(mpd_artist, INFO_MPD)
+               mpd_set_maxlen(mpd_artist);
+               init_mpd();
        END OBJ_THREAD(mpd_title, INFO_MPD)
-               if (arg) {
-                       sscanf(arg, "%d", &obj->data.i);
-                       if (obj->data.i > 0) {
-                               obj->data.i++;
-                       } else {
-                               ERR("mpd_title: invalid length argument");
-                               obj->data.i = 0;
-                       }
-               } else {
-                       obj->data.i = 0;
-               }
-       END OBJ_THREAD(mpd_random, INFO_MPD)
-       END OBJ_THREAD(mpd_repeat, INFO_MPD)
-       END OBJ_THREAD(mpd_elapsed, INFO_MPD)
-       END OBJ_THREAD(mpd_length, INFO_MPD)
+               mpd_set_maxlen(mpd_title);
+               init_mpd();
+       END OBJ_THREAD(mpd_random, INFO_MPD) init_mpd();
+       END OBJ_THREAD(mpd_repeat, INFO_MPD) init_mpd();
+       END OBJ_THREAD(mpd_elapsed, INFO_MPD) init_mpd();
+       END OBJ_THREAD(mpd_length, INFO_MPD) init_mpd();
        END OBJ_THREAD(mpd_track, INFO_MPD)
-               if (arg) {
-                       sscanf(arg, "%d", &obj->data.i);
-                       if (obj->data.i > 0) {
-                               obj->data.i++;
-                       } else {
-                               ERR("mpd_track: invalid length argument");
-                               obj->data.i = 0;
-                       }
-               } else {
-                       obj->data.i = 0;
-               }
+               mpd_set_maxlen(mpd_track);
+               init_mpd();
        END OBJ_THREAD(mpd_name, INFO_MPD)
-               if (arg) {
-                       sscanf(arg, "%d", &obj->data.i);
-                       if (obj->data.i > 0) {
-                               obj->data.i++;
-                       } else {
-                               ERR("mpd_name: invalid length argument");
-                               obj->data.i = 0;
-                       }
-               } else {
-                       obj->data.i = 0;
-               }
+               mpd_set_maxlen(mpd_name);
+               init_mpd();
        END OBJ_THREAD(mpd_file, INFO_MPD)
-               if (arg) {
-                       sscanf(arg, "%d", &obj->data.i);
-                       if (obj->data.i > 0) {
-                               obj->data.i++;
-                       } else {
-                               ERR("mpd_file: invalid length argument");
-                               obj->data.i = 0;
-                       }
-               } else {
-                       obj->data.i = 0;
-               }
-       END OBJ_THREAD(mpd_percent, INFO_MPD)
+               mpd_set_maxlen(mpd_file);
+               init_mpd();
+       END OBJ_THREAD(mpd_percent, INFO_MPD) init_mpd();
        END OBJ_THREAD(mpd_album, INFO_MPD)
-               if (arg) {
-                       sscanf(arg, "%d", &obj->data.i);
-                       if (obj->data.i > 0) {
-                               obj->data.i++;
-                       } else {
-                               ERR("mpd_album: invalid length argument");
-                               obj->data.i = 0;
-                       }
-               } else {
-                       obj->data.i = 0;
-               }
-       END OBJ_THREAD(mpd_vol, INFO_MPD)
-       END OBJ_THREAD(mpd_bitrate, INFO_MPD)
-       END OBJ_THREAD(mpd_status, INFO_MPD)
+               mpd_set_maxlen(mpd_album);
+               init_mpd();
+       END OBJ_THREAD(mpd_vol, INFO_MPD) init_mpd();
+       END OBJ_THREAD(mpd_bitrate, INFO_MPD) init_mpd();
+       END OBJ_THREAD(mpd_status, INFO_MPD) init_mpd();
        END OBJ_THREAD(mpd_bar, INFO_MPD)
                scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
+               init_mpd();
        END OBJ_THREAD(mpd_smart, INFO_MPD)
-               if (arg) {
-                       sscanf(arg, "%d", &obj->data.i);
-                       if (obj->data.i > 0) {
-                               obj->data.i++;
-                       } else {
-                               ERR("mpd_smart: invalid length argument");
-                               obj->data.i = 0;
-                       }
-               } else {
-                       obj->data.i = 0;
-               }
+               mpd_set_maxlen(mpd_smart);
+               init_mpd();
        END OBJ_THREAD(if_mpd_playing, INFO_MPD)
                obj_be_ifblock_if(obj);
+               init_mpd();
+#undef mpd_set_maxlen
 #endif /* MPD */
 #ifdef MOC
   END OBJ_THREAD(moc_state, INFO_MOC)
@@ -3466,7 +3409,7 @@ static int extract_variable_text_internal(struct text_object *retval, const char
 
 static void extract_variable_text(const char *p)
 {
-       free_text_objects(&global_root_object, 1);
+       free_text_objects(&global_root_object);
        if (tmpstring1) {
                free(tmpstring1);
                tmpstring1 = 0;
@@ -4203,7 +4146,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                memcpy(tmp_info, cur, sizeof(struct information));
                                parse_conky_vars(&subroot, p, p, tmp_info);
 
-                               free_text_objects(&subroot, 0);
+                               free_text_objects(&subroot);
                                free(tmp_info);
                        }
                        OBJ(execbar) {
@@ -4301,7 +4244,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        parse_conky_vars(&subroot, obj->data.execi.buffer, p, tmp_info);
                                        obj->data.execi.last_update = current_update_time;
                                }
-                               free_text_objects(&subroot, 0);
+                               free_text_objects(&subroot);
                                free(tmp_info);
                        }
                        OBJ(texeci) {
@@ -4625,7 +4568,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        DO_JUMP;
                                }
                                p[0] = '\0';
-                               free_text_objects(&subroot, 0);
+                               free_text_objects(&subroot);
                                free(tmp_info);
                        }
                        OBJ(if_existing) {
@@ -4879,96 +4822,78 @@ static void generate_text_internal(char *p, int p_max_size,
 #endif /* __FreeBSD__ __OpenBSD__ */
 
 #ifdef MPD
-                       OBJ(mpd_title) {
-                               int len = obj->data.i;
-                               if (len == 0 || len > p_max_size)
-                                       len = p_max_size;
-                               snprintf(p, len, "%s", cur->mpd.title);
-                       }
-                       OBJ(mpd_artist) {
-                               int len = obj->data.i;
-                               if (len == 0 || len > p_max_size)
-                                       len = p_max_size;
-                               snprintf(p, len, "%s", cur->mpd.artist);
-                       }
-                       OBJ(mpd_album) {
-                               int len = obj->data.i;
-                               if (len == 0 || len > p_max_size)
-                                       len = p_max_size;
-                               snprintf(p, len, "%s", cur->mpd.album);
-                       }
-                       OBJ(mpd_random) {
-                               snprintf(p, p_max_size, "%s", cur->mpd.random);
-                       }
-                       OBJ(mpd_repeat) {
-                               snprintf(p, p_max_size, "%s", cur->mpd.repeat);
-                       }
-                       OBJ(mpd_track) {
-                               int len = obj->data.i;
-                               if (len == 0 || len > p_max_size)
-                                       len = p_max_size;
-                               snprintf(p, len, "%s", cur->mpd.track);
-                       }
-                       OBJ(mpd_name) {
-                               int len = obj->data.i;
-                               if (len == 0 || len > p_max_size)
-                                       len = p_max_size;
-                               snprintf(p, len, "%s", cur->mpd.name);
-                       }
-                       OBJ(mpd_file) {
-                               int len = obj->data.i;
-                               if (len == 0 || len > p_max_size)
-                                       len = p_max_size;
-                               snprintf(p, len, "%s", cur->mpd.file);
-                       }
-                       OBJ(mpd_vol) {
-                               snprintf(p, p_max_size, "%i", cur->mpd.volume);
-                       }
-                       OBJ(mpd_bitrate) {
-                               snprintf(p, p_max_size, "%i", cur->mpd.bitrate);
-                       }
-                       OBJ(mpd_status) {
-                               snprintf(p, p_max_size, "%s", cur->mpd.status);
-                       }
+#define mpd_printf(fmt, val) \
+       snprintf(p, p_max_size, fmt, mpd_get_info()->val)
+#define mpd_sprintf(val) { \
+       if (!obj->data.i || obj->data.i > p_max_size) \
+               mpd_printf("%s", val); \
+       else \
+               snprintf(p, obj->data.i, "%s", mpd_get_info()->val); \
+}
+                       OBJ(mpd_title)
+                               mpd_sprintf(title);
+                       OBJ(mpd_artist)
+                               mpd_sprintf(artist);
+                       OBJ(mpd_album)
+                               mpd_sprintf(album);
+                       OBJ(mpd_random)
+                               mpd_printf("%s", random);
+                       OBJ(mpd_repeat)
+                               mpd_printf("%s", repeat);
+                       OBJ(mpd_track)
+                               mpd_sprintf(track);
+                       OBJ(mpd_name)
+                               mpd_sprintf(name);
+                       OBJ(mpd_file)
+                               mpd_sprintf(file);
+                       OBJ(mpd_vol)
+                               mpd_printf("%d", volume);
+                       OBJ(mpd_bitrate)
+                               mpd_printf("%d", bitrate);
+                       OBJ(mpd_status)
+                               mpd_printf("%s", status);
                        OBJ(mpd_elapsed) {
-                               format_media_player_time(p, p_max_size, cur->mpd.elapsed);
+                               format_media_player_time(p, p_max_size, mpd_get_info()->elapsed);
                        }
                        OBJ(mpd_length) {
-                               format_media_player_time(p, p_max_size, cur->mpd.length);
+                               format_media_player_time(p, p_max_size, mpd_get_info()->length);
                        }
                        OBJ(mpd_percent) {
                                spaced_print(p, p_max_size, "%*d", 4,
-                                               pad_percents, (int) (cur->mpd.progress * 100));
+                                               pad_percents, (int) (mpd_get_info()->progress * 100));
                        }
                        OBJ(mpd_bar) {
                                new_bar(p, obj->data.pair.a, obj->data.pair.b,
-                                       (int) (cur->mpd.progress * 255.0f));
+                                       (int) (mpd_get_info()->progress * 255.0f));
                        }
                        OBJ(mpd_smart) {
+                               struct mpd_s *mpd = mpd_get_info();
                                int len = obj->data.i;
                                if (len == 0 || len > p_max_size)
                                        len = p_max_size;
 
                                memset(p, 0, p_max_size);
-                               if (cur->mpd.artist && *cur->mpd.artist && cur->mpd.title
-                                               && *cur->mpd.title) {
-                                       snprintf(p, len, "%s - %s", cur->mpd.artist,
-                                               cur->mpd.title);
-                               } else if (cur->mpd.title && *cur->mpd.title) {
-                                       snprintf(p, len, "%s", cur->mpd.title);
-                               } else if (cur->mpd.artist && *cur->mpd.artist) {
-                                       snprintf(p, len, "%s", cur->mpd.artist);
-                               } else if (cur->mpd.file && *cur->mpd.file) {
-                                       snprintf(p, len, "%s", cur->mpd.file);
+                               if (mpd->artist && *mpd->artist &&
+                                   mpd->title && *mpd->title) {
+                                       snprintf(p, len, "%s - %s", mpd->artist,
+                                               mpd->title);
+                               } else if (mpd->title && *mpd->title) {
+                                       snprintf(p, len, "%s", mpd->title);
+                               } else if (mpd->artist && *mpd->artist) {
+                                       snprintf(p, len, "%s", mpd->artist);
+                               } else if (mpd->file && *mpd->file) {
+                                       snprintf(p, len, "%s", mpd->file);
                                } else {
                                        *p = 0;
                                }
                        }
                        OBJ(if_mpd_playing) {
-                               if (!cur->mpd.is_playing) {
+                               if (!mpd_get_info()->is_playing) {
                                        DO_JUMP;
                                }
                        }
+#undef mpd_sprintf
+#undef mpd_printf
 #endif
 
 #ifdef MOC
@@ -6940,49 +6865,10 @@ static void reload_config(void)
                free(info.mail);
        }
 
-#ifdef MPD
-       if (info.mpd.title) {
-               free(info.mpd.title);
-               info.mpd.title = NULL;
-       }
-       if (info.mpd.artist) {
-               free(info.mpd.artist);
-               info.mpd.artist = NULL;
-       }
-       if (info.mpd.album) {
-               free(info.mpd.album);
-               info.mpd.album = NULL;
-       }
-       if (info.mpd.random) {
-               free(info.mpd.random);
-               info.mpd.random = NULL;
-       }
-       if (info.mpd.repeat) {
-               free(info.mpd.repeat);
-               info.mpd.repeat = NULL;
-       }
-       if (info.mpd.track) {
-               free(info.mpd.track);
-               info.mpd.track = NULL;
-       }
-       if (info.mpd.name) {
-               free(info.mpd.name);
-               info.mpd.name = NULL;
-       }
-       if (info.mpd.file) {
-               free(info.mpd.file);
-               info.mpd.file = NULL;
-       }
-       if (info.mpd.status) {
-               free(info.mpd.status);
-               info.mpd.status = NULL;
-       }
-#endif
-
 #ifdef MOC
   free_moc(&info.moc);
 #endif
-  
+
 #ifdef X11
        free_fonts();
 #endif /* X11 */
@@ -7061,7 +6947,7 @@ static void clean_up(void)
        free_fonts();
 #endif /* X11 */
 
-       free_text_objects(&global_root_object, 1);
+       free_text_objects(&global_root_object);
        if (tmpstring1) {
                free(tmpstring1);
                tmpstring1 = 0;
@@ -7173,16 +7059,8 @@ static void set_default_configurations(void)
        short_units = 0;
        top_mem = 0;
 #ifdef MPD
-       strcpy(info.mpd.host, "localhost");
-       info.mpd.port = 6600;
-       info.mpd.status = NULL;
-       info.mpd.artist = NULL;
-       info.mpd.album = NULL;
-       info.mpd.title = NULL;
-       info.mpd.random = NULL;
-       info.mpd.track = NULL;
-       info.mpd.name = NULL;
-       info.mpd.file = NULL;
+       mpd_set_host("localhost");
+       mpd_set_port("6600");
 #endif
 #ifdef MOC
   init_moc(&info.moc);
@@ -7529,22 +7407,19 @@ static void load_config_file(const char *f)
 #ifdef MPD
                CONF("mpd_host") {
                        if (value) {
-                               strncpy(info.mpd.host, value, 127);
+                               mpd_set_host(value);
                        } else {
                                CONF_ERR;
                        }
                }
                CONF("mpd_port") {
-                       if (value) {
-                               info.mpd.port = strtol(value, 0, 0);
-                               if (info.mpd.port < 1 || info.mpd.port > 0xffff) {
-                                       CONF_ERR;
-                               }
+                       if (value && mpd_set_port(value)) {
+                               CONF_ERR;
                        }
                }
                CONF("mpd_password") {
                        if (value) {
-                               strncpy(info.mpd.password, value, 127);
+                               mpd_set_password(value);
                        } else {
                                CONF_ERR;
                        }
index 0a1de1a..70a19d7 100644 (file)
@@ -232,9 +232,6 @@ struct information {
 
        struct mail_s *mail;
        int mail_running;
-#ifdef MPD
-       struct mpd_s mpd;
-#endif
 #ifdef MOC
   struct moc_s moc;
 #endif
index 6c7cebe..d55fe05 100644 (file)
--- a/src/mpd.c
+++ b/src/mpd.c
 
 #include "conky.h"
 #include "logging.h"
+#include "timed_thread.h"
+#include "libmpdclient.h"
+#include "mpd.h"
 
-void init_mpd_stats(struct mpd_s *mpd)
+/* server connection data */
+static char mpd_host[128];
+static char mpd_password[128];
+static int mpd_port;
+
+/* global mpd information */
+static struct mpd_s mpd_info;
+
+/* number of users of the above struct */
+static int refcount = 0;
+
+void mpd_set_host(const char *host)
 {
-       if (mpd->artist == NULL) {
-               mpd->artist = malloc(text_buffer_size);
-       }
-       if (mpd->album == NULL) {
-               mpd->album = malloc(text_buffer_size);
-       }
-       if (mpd->title == NULL) {
-               mpd->title = malloc(text_buffer_size);
-       }
-       if (mpd->random == NULL) {
-               mpd->random = malloc(text_buffer_size);
-       }
-       if (mpd->repeat == NULL) {
-               mpd->repeat = malloc(text_buffer_size);
-       }
-       if (mpd->track == NULL) {
-               mpd->track = malloc(text_buffer_size);
-       }
-       if (mpd->status == NULL) {
-               mpd->status = malloc(text_buffer_size);
-       }
-       if (mpd->name == NULL) {
-               mpd->name = malloc(text_buffer_size);
-       }
-       if (mpd->file == NULL) {
-               mpd->file = malloc(text_buffer_size);
-       }
-       clear_mpd_stats(mpd);
+       snprintf(mpd_host, 128, "%s", host);
+}
+void mpd_set_password(const char *password)
+{
+       snprintf(mpd_password, 128, "%s", password);
+}
+void mpd_clear_password(void)
+{
+       *mpd_password = '\0';
+}
+int mpd_set_port(const char *port)
+{
+       int val;
+
+       val = strtol(port, 0, 0);
+       if (val < 1 || val > 0xffff)
+               return 1;
+       mpd_port = val;
+       return 0;
 }
 
-void free_mpd_vars(struct mpd_s *mpd)
+void init_mpd(void)
 {
-       if (mpd->title) {
-               free(mpd->title);
-               mpd->title = NULL;
-       }
-       if (mpd->artist) {
-               free(mpd->artist);
-               mpd->artist = NULL;
-       }
-       if (mpd->album) {
-               free(mpd->album);
-               mpd->album = NULL;
-       }
-       if (mpd->random) {
-               free(mpd->random);
-               mpd->random = NULL;
-       }
-       if (mpd->repeat) {
-               free(mpd->repeat);
-               mpd->repeat = NULL;
-       }
-       if (mpd->track) {
-               free(mpd->track);
-               mpd->track = NULL;
-       }
-       if (mpd->name) {
-               free(mpd->name);
-               mpd->name = NULL;
-       }
-       if (mpd->file) {
-               free(mpd->file);
-               mpd->file = NULL;
-       }
-       if (mpd->status) {
-               free(mpd->status);
-               mpd->status = NULL;
-       }
-       if (mpd->conn) {
-               mpd_closeConnection(mpd->conn);
-               mpd->conn = 0;
-       }
+       if (!(refcount++))      /* first client */
+               memset(&mpd_info, 0, sizeof(struct mpd_s));
+
+       refcount++;
 }
 
-void clear_mpd_stats(struct mpd_s *mpd)
+struct mpd_s *mpd_get_info(void)
 {
-       *mpd->name = 0;
-       *mpd->file = 0;
-       *mpd->artist = 0;
-       *mpd->album = 0;
-       *mpd->title = 0;
-       *mpd->random = 0;
-       *mpd->repeat = 0;
-       *mpd->track = 0;
-       *mpd->status = 0;
-       mpd->is_playing = 0;
-       mpd->bitrate = 0;
-       mpd->progress = 0;
-       mpd->elapsed = 0;
-       mpd->length = 0;
+       return &mpd_info;
 }
 
-void *update_mpd(void *arg)
+static void clear_mpd(void)
 {
-       struct mpd_s *mpd;
+#define xfree(x) if (x) free(x)
+       xfree(mpd_info.title);
+       xfree(mpd_info.artist);
+       xfree(mpd_info.album);
+       /* do not free() the const char *status! */
+       /* do not free() the const char *random! */
+       /* do not free() the const char *repeat! */
+       xfree(mpd_info.track);
+       xfree(mpd_info.name);
+       xfree(mpd_info.file);
+#undef xfree
+       memset(&mpd_info, 0, sizeof(struct mpd_s));
+}
 
-       if (arg == NULL) {
-               CRIT_ERR("update_mpd called with a null argument!");
+void free_mpd(void)
+{
+       if (!(--refcount))      /* last client */
+               clear_mpd();
+}
+
+static void *update_mpd_thread(void *) __attribute__((noreturn));
+
+void update_mpd(void)
+{
+       int interval;
+       static timed_thread *thread = NULL;
+
+       if (thread)
+               return;
+
+       interval = info.music_player_interval * 1000000;
+       thread = timed_thread_create(&update_mpd_thread, &thread, interval);
+       if (!thread) {
+               ERR("Failed to create MPD timed thread");
+               return;
        }
+       timed_thread_register(thread, &thread);
+       if (timed_thread_run(thread))
+               ERR("Failed to run MPD timed thread");
+}
+
+/* stringMAXdup dups at most text_buffer_size bytes */
+#define strmdup(x) strndup(x, text_buffer_size - 1)
 
-       mpd = (struct mpd_s *) arg;
+static void *update_mpd_thread(void *arg)
+{
+       static mpd_Connection *conn = NULL;
+       mpd_Status *status;
+       mpd_InfoEntity *entity;
+       timed_thread *me = *(timed_thread **)arg;
 
        while (1) {
-               mpd_Status *status;
-               mpd_InfoEntity *entity;
+               clear_mpd();
 
-               if (!mpd->conn) {
-                       mpd->conn = mpd_newConnection(mpd->host,
-                               mpd->port, 10);
-               }
-               if (strlen(mpd->password) > 1) {
-                       mpd_sendPasswordCommand(mpd->conn,
-                               mpd->password);
-                       mpd_finishCommand(mpd->conn);
+               if (!conn)
+                       conn = mpd_newConnection(mpd_host, mpd_port, 10);
+
+               if (*mpd_password) {
+                       mpd_sendPasswordCommand(conn, mpd_password);
+                       mpd_finishCommand(conn);
                }
 
-               timed_thread_lock(mpd->timed_thread);
+               timed_thread_lock(me);
 
-               if (mpd->conn->error || mpd->conn == NULL) {
-                       ERR("MPD error: %s\n", mpd->conn->errorStr);
-                       mpd_closeConnection(mpd->conn);
-                       mpd->conn = 0;
-                       clear_mpd_stats(mpd);
+               if (conn->error || conn == NULL) {
+                       ERR("MPD error: %s\n", conn->errorStr);
+                       mpd_closeConnection(conn);
+                       conn = 0;
+                       clear_mpd();
 
-                       strncpy(mpd->status, "MPD not responding",
-                               text_buffer_size - 1);
-                       timed_thread_unlock(mpd->timed_thread);
-                       if (timed_thread_test(mpd->timed_thread, 0)) {
-                               timed_thread_exit(mpd->timed_thread);
+                       mpd_info.status = "MPD not responding";
+                       timed_thread_unlock(me);
+                       if (timed_thread_test(me, 0)) {
+                               timed_thread_exit(me);
                        }
                        continue;
                }
 
-               mpd_sendStatusCommand(mpd->conn);
-               if ((status = mpd_getStatus(mpd->conn)) == NULL) {
-                       ERR("MPD error: %s\n", mpd->conn->errorStr);
-                       mpd_closeConnection(mpd->conn);
-                       mpd->conn = 0;
-                       clear_mpd_stats(mpd);
-
-                       strncpy(mpd->status, "MPD not responding",
-                               text_buffer_size - 1);
-                       timed_thread_unlock(mpd->timed_thread);
-                       if (timed_thread_test(mpd->timed_thread, 0)) {
-                               timed_thread_exit(mpd->timed_thread);
+               mpd_sendStatusCommand(conn);
+               if ((status = mpd_getStatus(conn)) == NULL) {
+                       ERR("MPD error: %s\n", conn->errorStr);
+                       mpd_closeConnection(conn);
+                       conn = 0;
+                       clear_mpd();
+
+                       mpd_info.status = "MPD not responding";
+                       timed_thread_unlock(me);
+                       if (timed_thread_test(me, 0)) {
+                               timed_thread_exit(me);
                        }
                        continue;
                }
-               mpd_finishCommand(mpd->conn);
-               if (mpd->conn->error) {
-                       // fprintf(stderr, "%s\n", mpd->conn->errorStr);
-                       mpd_closeConnection(mpd->conn);
-                       mpd->conn = 0;
-                       timed_thread_unlock(mpd->timed_thread);
-                       if (timed_thread_test(mpd->timed_thread, 0)) {
-                               timed_thread_exit(mpd->timed_thread);
+               mpd_finishCommand(conn);
+               if (conn->error) {
+                       // fprintf(stderr, "%s\n", conn->errorStr);
+                       mpd_closeConnection(conn);
+                       conn = 0;
+                       timed_thread_unlock(me);
+                       if (timed_thread_test(me, 0)) {
+                               timed_thread_exit(me);
                        }
                        continue;
                }
 
-               mpd->volume = status->volume;
+               mpd_info.volume = status->volume;
                /* if (status->error) {
                        printf("error: %s\n", status->error);
                } */
 
-               if (status->state == MPD_STATUS_STATE_PLAY) {
-                       strncpy(mpd->status, "Playing", text_buffer_size - 1);
+               switch(status->state) {
+                       case MPD_STATUS_STATE_PLAY:
+                               mpd_info.status = "Playing";
+                               break;
+                       case MPD_STATUS_STATE_STOP:
+                               mpd_info.status = "Stopped";
+                               break;
+                       case MPD_STATUS_STATE_PAUSE:
+                               mpd_info.status = "Paused";
+                               break;
+                       default:
+                               mpd_info.status = "";
+                               clear_mpd();
+                               break;
                }
-               if (status->state == MPD_STATUS_STATE_STOP) {
-                       clear_mpd_stats(mpd);
-                       strncpy(mpd->status, "Stopped", text_buffer_size - 1);
-               }
-               if (status->state == MPD_STATUS_STATE_PAUSE) {
-                       strncpy(mpd->status, "Paused", text_buffer_size - 1);
-               }
-               if (status->state == MPD_STATUS_STATE_UNKNOWN) {
-                       clear_mpd_stats(mpd);
-                       *mpd->status = 0;
-               }
-               if (status->state == MPD_STATUS_STATE_PLAY
-                               || status->state == MPD_STATUS_STATE_PAUSE) {
-                       mpd->is_playing = 1;
-                       mpd->bitrate = status->bitRate;
-                       mpd->progress = (float) status->elapsedTime /
+
+               if (status->state == MPD_STATUS_STATE_PLAY ||
+                   status->state == MPD_STATUS_STATE_PAUSE) {
+                       mpd_info.is_playing = 1;
+                       mpd_info.bitrate = status->bitRate;
+                       mpd_info.progress = (float) status->elapsedTime /
                                status->totalTime;
-                       mpd->elapsed = status->elapsedTime;
-                       mpd->length = status->totalTime;
+                       mpd_info.elapsed = status->elapsedTime;
+                       mpd_info.length = status->totalTime;
                        if (status->random == 0) {
-                               strcpy(mpd->random, "Off");
+                               mpd_info.random = "Off";
                        } else if (status->random == 1) {
-                               strcpy(mpd->random, "On");
+                               mpd_info.random = "On";
                        } else {
-                               *mpd->random = 0;
+                               mpd_info.random = "";
                        }
                        if (status->repeat == 0) {
-                               strcpy(mpd->repeat, "Off");
+                               mpd_info.repeat = "Off";
                        } else if (status->repeat == 1) {
-                               strcpy(mpd->repeat, "On");
+                               mpd_info.repeat = "On";
                        } else {
-                               *mpd->repeat = 0;
+                               mpd_info.repeat = "";
                        }
                }
 
-               if (mpd->conn->error) {
-                       // fprintf(stderr, "%s\n", mpd->conn->errorStr);
-                       mpd_closeConnection(mpd->conn);
-                       mpd->conn = 0;
-                       timed_thread_unlock(mpd->timed_thread);
-                       if (timed_thread_test(mpd->timed_thread, 0)) {
-                               timed_thread_exit(mpd->timed_thread);
+               if (conn->error) {
+                       // fprintf(stderr, "%s\n", conn->errorStr);
+                       mpd_closeConnection(conn);
+                       conn = 0;
+                       timed_thread_unlock(me);
+                       if (timed_thread_test(me, 0)) {
+                               timed_thread_exit(me);
                        }
                        continue;
                }
 
-               mpd_sendCurrentSongCommand(mpd->conn);
-               while ((entity = mpd_getNextInfoEntity(mpd->conn))) {
+               mpd_sendCurrentSongCommand(conn);
+               while ((entity = mpd_getNextInfoEntity(conn))) {
                        mpd_Song *song = entity->info.song;
 
                        if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
                                mpd_freeInfoEntity(entity);
                                continue;
                        }
-
-                       if (song->artist) {
-                               strncpy(mpd->artist, song->artist,
-                                       text_buffer_size - 1);
-                       } else {
-                               *mpd->artist = 0;
-                       }
-                       if (song->album) {
-                               strncpy(mpd->album, song->album,
-                                       text_buffer_size - 1);
-                       } else {
-                               *mpd->album = 0;
-                       }
-                       if (song->title) {
-                               strncpy(mpd->title, song->title,
-                                       text_buffer_size - 1);
-                       } else {
-                               *mpd->title = 0;
-                       }
-                       if (song->track) {
-                               strncpy(mpd->track, song->track,
-                                       text_buffer_size - 1);
-                       } else {
-                               *mpd->track = 0;
-                       }
-                       if (song->name) {
-                               strncpy(mpd->name, song->name,
-                                       text_buffer_size - 1);
-                       } else {
-                               *mpd->name = 0;
-                       }
-                       if (song->file) {
-                               strncpy(mpd->file, song->file,
-                                       text_buffer_size - 1);
-                       } else {
-                               *mpd->file = 0;
-                       }
+#define SONGSET(x) if(song->x) mpd_info.x = strmdup(song->x)
+                       SONGSET(artist);
+                       SONGSET(album);
+                       SONGSET(title);
+                       SONGSET(track);
+                       SONGSET(name);
+                       SONGSET(file);
+#undef SONGSET
                        if (entity != NULL) {
                                mpd_freeInfoEntity(entity);
                                entity = NULL;
                        }
                }
-               if (entity != NULL) {
-                       mpd_freeInfoEntity(entity);
-                       entity = NULL;
-               }
-               mpd_finishCommand(mpd->conn);
-               if (mpd->conn->error) {
-                       // fprintf(stderr, "%s\n", mpd->conn->errorStr);
-                       mpd_closeConnection(mpd->conn);
-                       mpd->conn = 0;
-                       timed_thread_unlock(mpd->timed_thread);
-                       if (timed_thread_test(mpd->timed_thread, 0)) {
-                               timed_thread_exit(mpd->timed_thread);
+               mpd_finishCommand(conn);
+               if (conn->error) {
+                       // fprintf(stderr, "%s\n", conn->errorStr);
+                       mpd_closeConnection(conn);
+                       conn = 0;
+                       timed_thread_unlock(me);
+                       if (timed_thread_test(me, 0)) {
+                               timed_thread_exit(me);
                        }
                        continue;
                }
 
-               timed_thread_unlock(mpd->timed_thread);
-               if (mpd->conn->error) {
-                       // fprintf(stderr, "%s\n", mpd->conn->errorStr);
-                       mpd_closeConnection(mpd->conn);
-                       mpd->conn = 0;
-                       if (timed_thread_test(mpd->timed_thread, 0)) {
-                               timed_thread_exit(mpd->timed_thread);
+               timed_thread_unlock(me);
+               if (conn->error) {
+                       // fprintf(stderr, "%s\n", conn->errorStr);
+                       mpd_closeConnection(conn);
+                       conn = 0;
+                       if (timed_thread_test(me, 0)) {
+                               timed_thread_exit(me);
                        }
                        continue;
                }
 
                mpd_freeStatus(status);
-               /* if (mpd->conn) {
-                       mpd_closeConnection(mpd->conn);
-                       mpd->conn = 0;
+               /* if (conn) {
+                       mpd_closeConnection(conn);
+                       conn = 0;
                } */
-               if (timed_thread_test(mpd->timed_thread, 0)) {
-                       timed_thread_exit(mpd->timed_thread);
+               if (timed_thread_test(me, 0)) {
+                       timed_thread_exit(me);
                }
                continue;
        }
        /* never reached */
 }
+
index b06871f..65047fc 100644 (file)
--- a/src/mpd.h
+++ b/src/mpd.h
@@ -1,37 +1,36 @@
 #ifndef MPD_H_
 #define MPD_H_
 
-#include "libmpdclient.h"
-#include "timed_thread.h"
+//#include "conky.h"
 
 struct mpd_s {
        char *title;
        char *artist;
        char *album;
-       char *status;
-       char *random;
-       char *repeat;
+       const char *status;
+       const char *random;
+       const char *repeat;
        char *track;
        char *name;
        char *file;
        int is_playing;
        int volume;
-       unsigned int port;
-       char host[128];
-       char password[128];
        float progress;
        int bitrate;
        int length;
        int elapsed;
-       mpd_Connection *conn;
-       timed_thread *timed_thread;
 };
 
-#include "conky.h"
+/* functions for setting the configuration values */
+void mpd_set_host(const char *);
+void mpd_set_password(const char *);
+void mpd_clear_password(void);
+int mpd_set_port(const char *);
 
-extern void init_mpd_stats(struct mpd_s *mpd);
-void clear_mpd_stats(struct mpd_s *mpd);
-void *update_mpd(void *) __attribute__((noreturn));
-void free_mpd_vars(struct mpd_s *mpd);
+/* text object functions */
+void init_mpd(void);
+struct mpd_s *mpd_get_info(void);
+void free_mpd(void);
+void update_mpd(void);
 
 #endif /*MPD_H_*/