diff --git a/src/core.cc b/src/core.cc index 1410fa35..85e5aa08 100644 --- a/src/core.cc +++ b/src/core.cc @@ -1472,39 +1472,28 @@ struct text_object *construct_text_object(char *s, const char *arg, long #undef mpd_set_maxlen #endif /* BUILD_MPD */ #ifdef BUILD_MOC - END OBJ(moc_state, &update_moc) + END OBJ(moc_state, 0) obj->callbacks.print = &print_moc_state; - obj->callbacks.free = &free_moc; - END OBJ(moc_file, &update_moc) + END OBJ(moc_file, 0) obj->callbacks.print = &print_moc_file; - obj->callbacks.free = &free_moc; - END OBJ(moc_title, &update_moc) + END OBJ(moc_title, 0) obj->callbacks.print = &print_moc_title; - obj->callbacks.free = &free_moc; - END OBJ(moc_artist, &update_moc) + END OBJ(moc_artist, 0) obj->callbacks.print = &print_moc_artist; - obj->callbacks.free = &free_moc; - END OBJ(moc_song, &update_moc) + END OBJ(moc_song, 0) obj->callbacks.print = &print_moc_song; - obj->callbacks.free = &free_moc; - END OBJ(moc_album, &update_moc) + END OBJ(moc_album, 0) obj->callbacks.print = &print_moc_album; - obj->callbacks.free = &free_moc; - END OBJ(moc_totaltime, &update_moc) + END OBJ(moc_totaltime, 0) obj->callbacks.print = &print_moc_totaltime; - obj->callbacks.free = &free_moc; - END OBJ(moc_timeleft, &update_moc) + END OBJ(moc_timeleft, 0) obj->callbacks.print = &print_moc_timeleft; - obj->callbacks.free = &free_moc; - END OBJ(moc_curtime, &update_moc) + END OBJ(moc_curtime, 0) obj->callbacks.print = &print_moc_curtime; - obj->callbacks.free = &free_moc; - END OBJ(moc_bitrate, &update_moc) + END OBJ(moc_bitrate, 0) obj->callbacks.print = &print_moc_bitrate; - obj->callbacks.free = &free_moc; - END OBJ(moc_rate, &update_moc) + END OBJ(moc_rate, 0) obj->callbacks.print = &print_moc_rate; - obj->callbacks.free = &free_moc; #endif /* BUILD_MOC */ #ifdef BUILD_XMMS2 END OBJ(xmms2_artist, &update_xmms2) diff --git a/src/moc.cc b/src/moc.cc index c22017bc..10e4babd 100644 --- a/src/moc.cc +++ b/src/moc.cc @@ -29,127 +29,99 @@ #include #include #include +#include #include -static struct { - char *state; - char *file; - char *title; - char *artist; - char *song; - char *album; - char *totaltime; - char *timeleft; - char *curtime; - char *bitrate; - char *rate; -} moc; +#include "update-cb.hh" -static timed_thread_ptr moc_thread; +namespace { + struct moc_result { + std::string state; + std::string file; + std::string title; + std::string artist; + std::string song; + std::string album; + std::string totaltime; + std::string timeleft; + std::string curtime; + std::string bitrate; + std::string rate; + }; -void free_moc(struct text_object *obj) -{ - (void)obj; - free_and_zero(moc.state); - free_and_zero(moc.file); - free_and_zero(moc.title); - free_and_zero(moc.artist); - free_and_zero(moc.song); - free_and_zero(moc.album); - free_and_zero(moc.totaltime); - free_and_zero(moc.timeleft); - free_and_zero(moc.curtime); - free_and_zero(moc.bitrate); - free_and_zero(moc.rate); -} + class moc_cb: public conky::callback { + typedef conky::callback Base; -static void update_infos(void) -{ - FILE *fp; + protected: + virtual void work(); - free_moc(NULL); - fp = popen("mocp -i", "r"); - if (!fp) { - moc.state = strndup("Can't run 'mocp -i'", text_buffer_size.get(*state)); - return; - } + public: + moc_cb(uint32_t period) + : Base(period, false, Tuple()) + {} + }; - while (1) { - char line[100]; - char *p; + void moc_cb::work() + { + moc_result moc; + FILE *fp; - /* Read a line from the pipe and strip the possible '\n'. */ - if (!fgets(line, 100, fp)) - break; - if ((p = strrchr(line, '\n'))) - *p = '\0'; + fp = popen("mocp -i", "r"); + if (!fp) { + moc.state = "Can't run 'mocp -i'"; + } else { + while (1) { + char line[100]; + char *p; - /* Parse infos. */ - if (strncmp(line, "State:", 6) == 0) - moc.state = strndup(line + 7, text_buffer_size.get(*state)); - else if (strncmp(line, "File:", 5) == 0) - moc.file = strndup(line + 6, text_buffer_size.get(*state)); - else if (strncmp(line, "Title:", 6) == 0) - moc.title = strndup(line + 7, text_buffer_size.get(*state)); - else if (strncmp(line, "Artist:", 7) == 0) - moc.artist = strndup(line + 8, text_buffer_size.get(*state)); - else if (strncmp(line, "SongTitle:", 10) == 0) - moc.song = strndup(line + 11, text_buffer_size.get(*state)); - else if (strncmp(line, "Album:", 6) == 0) - moc.album = strndup(line + 7, text_buffer_size.get(*state)); - else if (strncmp(line, "TotalTime:", 10) == 0) - moc.totaltime = strndup(line + 11, text_buffer_size.get(*state)); - else if (strncmp(line, "TimeLeft:", 9) == 0) - moc.timeleft = strndup(line + 10, text_buffer_size.get(*state)); - else if (strncmp(line, "CurrentTime:", 12) == 0) - moc.curtime = strndup(line + 13, text_buffer_size.get(*state)); - else if (strncmp(line, "Bitrate:", 8) == 0) - moc.bitrate = strndup(line + 9, text_buffer_size.get(*state)); - else if (strncmp(line, "Rate:", 5) == 0) - moc.rate = strndup(line + 6, text_buffer_size.get(*state)); - } + /* Read a line from the pipe and strip the possible '\n'. */ + if (!fgets(line, 100, fp)) + break; + if ((p = strrchr(line, '\n'))) + *p = '\0'; - pclose(fp); -} - -static void update_moc_loop(thread_handle &handle) -{ - while (1) { - { - std::lock_guard lock(handle.mutex()); - update_infos(); - } - if (handle.test(0)) { - return; + /* Parse infos. */ + if (strncmp(line, "State:", 6) == 0) + moc.state = line + 7; + else if (strncmp(line, "File:", 5) == 0) + moc.file = line + 6; + else if (strncmp(line, "Title:", 6) == 0) + moc.title = line + 7; + else if (strncmp(line, "Artist:", 7) == 0) + moc.artist = line + 8; + else if (strncmp(line, "SongTitle:", 10) == 0) + moc.song = line + 11; + else if (strncmp(line, "Album:", 6) == 0) + moc.album = line + 7; + else if (strncmp(line, "TotalTime:", 10) == 0) + moc.totaltime = line + 11; + else if (strncmp(line, "TimeLeft:", 9) == 0) + moc.timeleft = line + 10; + else if (strncmp(line, "CurrentTime:", 12) == 0) + moc.curtime = line + 13; + else if (strncmp(line, "Bitrate:", 8) == 0) + moc.bitrate = line + 9; + else if (strncmp(line, "Rate:", 5) == 0) + moc.rate = line + 6; + } } + + pclose(fp); + + std::lock_guard l(result_mutex); + result = moc; } - /* never reached */ -} - -static int run_moc_thread(std::chrono::microseconds interval) -{ - if (moc_thread) - return 0; - - moc_thread = timed_thread::create(std::bind(update_moc_loop, std::placeholders::_1), interval); - if (!moc_thread) { - NORM_ERR("Failed to create MOC timed thread"); - return 1; - } - return 0; -} - -int update_moc(void) -{ - run_moc_thread(std::chrono::microseconds(long(music_player_interval.get(*state) * 1000000))); - return 0; } #define MOC_PRINT_GENERATOR(type, alt) \ void print_moc_##type(struct text_object *obj, char *p, int p_max_size) \ { \ (void)obj; \ - snprintf(p, p_max_size, "%s", (moc.type ? moc.type : alt)); \ + uint32_t period = std::max( \ + std::lround(music_player_interval.get(*state)/active_update_interval()), 1l \ + ); \ + const moc_result &moc = conky::register_cb(period)->get_result_copy(); \ + snprintf(p, p_max_size, "%s", (moc.type.length() ? moc.type.c_str() : alt)); \ } MOC_PRINT_GENERATOR(state, "??") diff --git a/src/moc.h b/src/moc.h index 5cc53050..d524bdca 100644 --- a/src/moc.h +++ b/src/moc.h @@ -24,9 +24,6 @@ #ifndef MOC_H_ #define MOC_H_ -int update_moc(void); -void free_moc(struct text_object *); - void print_moc_state(struct text_object *, char *, int); void print_moc_file(struct text_object *, char *, int); void print_moc_title(struct text_object *, char *, int);