1 /* Conky, a system monitor, based on torsmo
3 * Any original torsmo code is licensed under the BSD license
5 * All code written since the fork of torsmo is licensed under the GPL
7 * Please see COPYING for details
9 * Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
11 * All rights reserved.
13 * This program is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 #include "libmpdclient.h"
33 timed_thread *mpd_timed_thread = NULL;
35 void clear_mpd_stats(struct information *current_info);
37 void init_mpd_stats(struct information *current_info)
39 if (current_info->mpd.artist == NULL) {
40 current_info->mpd.artist = malloc(text_buffer_size);
42 if (current_info->mpd.album == NULL) {
43 current_info->mpd.album = malloc(text_buffer_size);
45 if (current_info->mpd.title == NULL) {
46 current_info->mpd.title = malloc(text_buffer_size);
48 if (current_info->mpd.random == NULL) {
49 current_info->mpd.random = malloc(text_buffer_size);
51 if (current_info->mpd.repeat == NULL) {
52 current_info->mpd.repeat = malloc(text_buffer_size);
54 if (current_info->mpd.track == NULL) {
55 current_info->mpd.track = malloc(text_buffer_size);
57 if (current_info->mpd.status == NULL) {
58 current_info->mpd.status = malloc(text_buffer_size);
60 if (current_info->mpd.name == NULL) {
61 current_info->mpd.name = malloc(text_buffer_size);
63 if (current_info->mpd.file == NULL) {
64 current_info->mpd.file = malloc(text_buffer_size);
66 clear_mpd_stats(current_info);
69 void free_mpd_vars(struct information *current_info)
71 if (current_info->mpd.title) {
72 free(current_info->mpd.title);
73 current_info->mpd.title = NULL;
75 if (current_info->mpd.artist) {
76 free(current_info->mpd.artist);
77 current_info->mpd.artist = NULL;
79 if (current_info->mpd.album) {
80 free(current_info->mpd.album);
81 current_info->mpd.album = NULL;
83 if (current_info->mpd.random) {
84 free(current_info->mpd.random);
85 current_info->mpd.random = NULL;
87 if (current_info->mpd.repeat) {
88 free(current_info->mpd.repeat);
89 current_info->mpd.repeat = NULL;
91 if (current_info->mpd.track) {
92 free(current_info->mpd.track);
93 current_info->mpd.track = NULL;
95 if (current_info->mpd.name) {
96 free(current_info->mpd.name);
97 current_info->mpd.name = NULL;
99 if (current_info->mpd.file) {
100 free(current_info->mpd.file);
101 current_info->mpd.file = NULL;
103 if (current_info->mpd.status) {
104 free(current_info->mpd.status);
105 current_info->mpd.status = NULL;
107 if (current_info->conn) {
108 mpd_closeConnection(current_info->conn);
109 current_info->conn = 0;
113 void clear_mpd_stats(struct information *current_info)
115 *current_info->mpd.name = 0;
116 *current_info->mpd.file = 0;
117 *current_info->mpd.artist = 0;
118 *current_info->mpd.album = 0;
119 *current_info->mpd.title = 0;
120 *current_info->mpd.random = 0;
121 *current_info->mpd.repeat = 0;
122 *current_info->mpd.track = 0;
123 *current_info->mpd.status = 0;
124 current_info->mpd.bitrate = 0;
125 current_info->mpd.progress = 0;
126 current_info->mpd.elapsed = 0;
127 current_info->mpd.length = 0;
130 void *update_mpd(void *arg)
132 struct information *current_info = &info;
135 /* make gcc happy (unused argument) */
139 if (!current_info->conn) {
140 current_info->conn = mpd_newConnection(current_info->mpd.host,
141 current_info->mpd.port, 10);
143 if (strlen(current_info->mpd.password) > 1) {
144 mpd_sendPasswordCommand(current_info->conn,
145 current_info->mpd.password);
146 mpd_finishCommand(current_info->conn);
149 timed_thread_lock(mpd_timed_thread);
151 if (current_info->conn->error || current_info->conn == NULL) {
152 // ERR("%MPD error: s\n", current_info->conn->errorStr);
153 mpd_closeConnection(current_info->conn);
154 current_info->conn = 0;
155 clear_mpd_stats(current_info);
157 strncpy(current_info->mpd.status, "MPD not responding",
158 text_buffer_size - 1);
159 timed_thread_unlock(mpd_timed_thread);
160 if (timed_thread_test(mpd_timed_thread)) {
161 timed_thread_exit(mpd_timed_thread);
167 mpd_InfoEntity *entity;
169 mpd_sendStatusCommand(current_info->conn);
170 if ((status = mpd_getStatus(current_info->conn)) == NULL) {
171 // ERR("MPD error: %s\n", current_info->conn->errorStr);
172 mpd_closeConnection(current_info->conn);
173 current_info->conn = 0;
174 clear_mpd_stats(current_info);
176 strncpy(current_info->mpd.status, "MPD not responding",
177 text_buffer_size - 1);
178 timed_thread_unlock(mpd_timed_thread);
179 if (timed_thread_test(mpd_timed_thread)) {
180 timed_thread_exit(mpd_timed_thread);
184 mpd_finishCommand(current_info->conn);
185 if (current_info->conn->error) {
186 // fprintf(stderr, "%s\n", current_info->conn->errorStr);
187 mpd_closeConnection(current_info->conn);
188 current_info->conn = 0;
189 timed_thread_unlock(mpd_timed_thread);
190 if (timed_thread_test(mpd_timed_thread)) {
191 timed_thread_exit(mpd_timed_thread);
196 current_info->mpd.volume = status->volume;
197 /* if (status->error) {
198 printf("error: %s\n", status->error);
201 if (status->state == MPD_STATUS_STATE_PLAY) {
202 strncpy(current_info->mpd.status, "Playing", text_buffer_size - 1);
204 if (status->state == MPD_STATUS_STATE_STOP) {
205 clear_mpd_stats(current_info);
206 strncpy(current_info->mpd.status, "Stopped", text_buffer_size - 1);
208 if (status->state == MPD_STATUS_STATE_PAUSE) {
209 strncpy(current_info->mpd.status, "Paused", text_buffer_size - 1);
211 if (status->state == MPD_STATUS_STATE_UNKNOWN) {
212 clear_mpd_stats(current_info);
213 *current_info->mpd.status = 0;
215 if (status->state == MPD_STATUS_STATE_PLAY
216 || status->state == MPD_STATUS_STATE_PAUSE) {
217 current_info->mpd.bitrate = status->bitRate;
218 current_info->mpd.progress = (float) status->elapsedTime /
220 current_info->mpd.elapsed = status->elapsedTime;
221 current_info->mpd.length = status->totalTime;
222 if (status->random == 0) {
223 strcpy(current_info->mpd.random, "Off");
224 } else if (status->random == 1) {
225 strcpy(current_info->mpd.random, "On");
227 *current_info->mpd.random = 0;
229 if (status->repeat == 0) {
230 strcpy(current_info->mpd.repeat, "Off");
231 } else if (status->repeat == 1) {
232 strcpy(current_info->mpd.repeat, "On");
234 *current_info->mpd.repeat = 0;
238 if (current_info->conn->error) {
239 // fprintf(stderr, "%s\n", current_info->conn->errorStr);
240 mpd_closeConnection(current_info->conn);
241 current_info->conn = 0;
242 timed_thread_unlock(mpd_timed_thread);
243 if (timed_thread_test(mpd_timed_thread)) {
244 timed_thread_exit(mpd_timed_thread);
249 mpd_sendCurrentSongCommand(current_info->conn);
250 while ((entity = mpd_getNextInfoEntity(current_info->conn))) {
251 mpd_Song *song = entity->info.song;
253 if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
254 mpd_freeInfoEntity(entity);
259 strncpy(current_info->mpd.artist, song->artist,
260 text_buffer_size - 1);
262 *current_info->mpd.artist = 0;
265 strncpy(current_info->mpd.album, song->album,
266 text_buffer_size - 1);
268 *current_info->mpd.album = 0;
271 strncpy(current_info->mpd.title, song->title,
272 text_buffer_size - 1);
274 *current_info->mpd.title = 0;
277 strncpy(current_info->mpd.track, song->track,
278 text_buffer_size - 1);
280 *current_info->mpd.track = 0;
283 strncpy(current_info->mpd.name, song->name,
284 text_buffer_size - 1);
286 *current_info->mpd.name = 0;
289 strncpy(current_info->mpd.file, song->file,
290 text_buffer_size - 1);
292 *current_info->mpd.file = 0;
294 if (entity != NULL) {
295 mpd_freeInfoEntity(entity);
299 if (entity != NULL) {
300 mpd_freeInfoEntity(entity);
303 mpd_finishCommand(current_info->conn);
304 if (current_info->conn->error) {
305 // fprintf(stderr, "%s\n", current_info->conn->errorStr);
306 mpd_closeConnection(current_info->conn);
307 current_info->conn = 0;
308 timed_thread_unlock(mpd_timed_thread);
309 if (timed_thread_test(mpd_timed_thread)) {
310 timed_thread_exit(mpd_timed_thread);
315 timed_thread_unlock(mpd_timed_thread);
316 if (current_info->conn->error) {
317 // fprintf(stderr, "%s\n", current_info->conn->errorStr);
318 mpd_closeConnection(current_info->conn);
319 current_info->conn = 0;
320 if (timed_thread_test(mpd_timed_thread)) {
321 timed_thread_exit(mpd_timed_thread);
326 mpd_freeStatus(status);
327 /* if (current_info->conn) {
328 mpd_closeConnection(current_info->conn);
329 current_info->conn = 0;
331 if (timed_thread_test(mpd_timed_thread)) {
332 timed_thread_exit(mpd_timed_thread);