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 <xmmsclient/xmmsclient.h>
39 static void xmms_alloc(struct information *ptr)
41 if (ptr->xmms2.status == NULL) {
42 ptr->xmms2.status = malloc(TEXT_BUFFER_SIZE);
43 ptr->xmms2.status[0] = '\0';
46 if (ptr->xmms2.artist == NULL) {
47 ptr->xmms2.artist = malloc(TEXT_BUFFER_SIZE);
48 ptr->xmms2.artist[0] = '\0';
51 if (ptr->xmms2.album == NULL) {
52 ptr->xmms2.album = malloc(TEXT_BUFFER_SIZE);
53 ptr->xmms2.album[0] = '\0';
56 if (ptr->xmms2.title == NULL) {
57 ptr->xmms2.title = malloc(TEXT_BUFFER_SIZE);
58 ptr->xmms2.title[0] = '\0';
61 if (ptr->xmms2.genre == NULL) {
62 ptr->xmms2.genre = malloc(TEXT_BUFFER_SIZE);
63 ptr->xmms2.genre[0] = '\0';
66 if (ptr->xmms2.comment == NULL) {
67 ptr->xmms2.comment = malloc(TEXT_BUFFER_SIZE);
68 ptr->xmms2.comment[0] = '\0';
71 if (ptr->xmms2.url == NULL) {
72 ptr->xmms2.url = malloc(TEXT_BUFFER_SIZE);
73 ptr->xmms2.url[0] = '\0';
76 if (ptr->xmms2.date == NULL) {
77 ptr->xmms2.date = malloc(TEXT_BUFFER_SIZE);
78 ptr->xmms2.date[0] = '\0';
82 static void xmms_clear(struct information *ptr)
85 ptr->xmms2.artist[0] = '\0';
86 ptr->xmms2.album[0] = '\0';
87 ptr->xmms2.title[0] = '\0';
88 ptr->xmms2.genre[0] = '\0';
89 ptr->xmms2.comment[0] = '\0';
90 ptr->xmms2.url[0] = '\0';
91 ptr->xmms2.date[0] = '\0';
93 ptr->xmms2.tracknr = 0;
95 ptr->xmms2.bitrate = 0;
96 ptr->xmms2.duration = 0;
97 ptr->xmms2.elapsed = 0;
99 ptr->xmms2.progress = 0;
100 ptr->xmms2.timesplayed = -1;
103 void connection_lost(void *p)
105 struct information *ptr = p;
106 ptr->xmms2_conn_state = CONN_NO;
108 fprintf(stderr,"Conky: xmms2 connection failed. %s\n",
109 xmmsc_get_last_error ( ptr->xmms2_conn ));
115 void handle_curent_id(xmmsc_result_t *res, void *p)
118 struct information *ptr = p;
120 if (xmmsc_result_get_uint(res, ¤t_id)) {
122 xmmsc_result_t *res2;
124 res2 = xmmsc_medialib_get_info(ptr->xmms2_conn, current_id);
125 xmmsc_result_wait(res2);
129 ptr->xmms2.id = current_id;
133 xmmsc_result_get_dict_entry_string(res2, "artist", &temp);
135 strncpy(ptr->xmms2.artist, temp, TEXT_BUFFER_SIZE - 1);
137 strncpy(ptr->xmms2.artist, "[Unknown]", TEXT_BUFFER_SIZE - 1);
140 xmmsc_result_get_dict_entry_string(res2, "title", &temp);
142 strncpy(ptr->xmms2.title, temp, TEXT_BUFFER_SIZE - 1);
144 strncpy(ptr->xmms2.title, "[Unknown]", TEXT_BUFFER_SIZE - 1);
147 xmmsc_result_get_dict_entry_string(res2, "album", &temp);
149 strncpy(ptr->xmms2.album, temp, TEXT_BUFFER_SIZE - 1);
151 strncpy(ptr->xmms2.album, "[Unknown]", TEXT_BUFFER_SIZE - 1);
154 xmmsc_result_get_dict_entry_string(res2, "genre", &temp);
157 strncpy(ptr->xmms2.genre, temp, TEXT_BUFFER_SIZE - 1);
159 strncpy(ptr->xmms2.genre, "[Unknown]", TEXT_BUFFER_SIZE - 1);
162 xmmsc_result_get_dict_entry_string(res2, "comment", &temp);
164 strncpy(ptr->xmms2.comment, temp, TEXT_BUFFER_SIZE - 1);
166 strncpy(ptr->xmms2.comment, "", TEXT_BUFFER_SIZE - 1);
169 xmmsc_result_get_dict_entry_string(res2, "url", &temp);
171 strncpy(ptr->xmms2.url, temp, TEXT_BUFFER_SIZE - 1);
173 strncpy(ptr->xmms2.url, "[Unknown]", TEXT_BUFFER_SIZE - 1);
176 xmmsc_result_get_dict_entry_string(res2, "date", &temp);
178 strncpy(ptr->xmms2.date, temp, TEXT_BUFFER_SIZE - 1);
180 strncpy(ptr->xmms2.date, "????", TEXT_BUFFER_SIZE - 1);
185 xmmsc_result_get_dict_entry_int(res2, "tracknr", &itemp);
186 ptr->xmms2.tracknr = itemp;
188 xmmsc_result_get_dict_entry_int(res2, "duration", &itemp);
189 ptr->xmms2.duration = itemp;
191 xmmsc_result_get_dict_entry_int(res2, "bitrate", &itemp);
192 ptr->xmms2.bitrate = itemp / 1000;
194 xmmsc_result_get_dict_entry_int(res2, "size", &itemp);
195 ptr->xmms2.size = (float) itemp / 1048576;
197 xmmsc_result_get_dict_entry_int( res2, "timesplayed", &itemp );
198 ptr->xmms2.timesplayed = itemp;
200 xmmsc_result_unref(res2);
204 void handle_playtime(xmmsc_result_t *res, void *p)
206 struct information *ptr = p;
207 xmmsc_result_t *res2;
210 if (xmmsc_result_iserror(res)) {
214 if (!xmmsc_result_get_uint(res, &play_time)) {
218 res2 = xmmsc_result_restart(res);
219 xmmsc_result_unref(res2);
221 ptr->xmms2.elapsed = play_time;
222 ptr->xmms2.progress = (float) play_time / ptr->xmms2.duration;
225 void handle_playback_state_change(xmmsc_result_t *res, void *p)
227 struct information *ptr = p;
230 if (xmmsc_result_iserror(res)) {
234 if (!xmmsc_result_get_uint(res, &pb_state)) {
239 case XMMS_PLAYBACK_STATUS_PLAY:
240 strncpy(ptr->xmms2.status, "Playing", TEXT_BUFFER_SIZE - 1);
242 case XMMS_PLAYBACK_STATUS_PAUSE:
243 strncpy(ptr->xmms2.status, "Paused", TEXT_BUFFER_SIZE - 1);
245 case XMMS_PLAYBACK_STATUS_STOP:
246 strncpy(ptr->xmms2.status, "Stopped", TEXT_BUFFER_SIZE - 1);
249 strncpy(ptr->xmms2.status, "Unknown", TEXT_BUFFER_SIZE - 1);
253 void handle_playlist_loaded(xmmsc_result_t *res, void *p) {
254 struct information *ptr = p;
256 if (ptr->xmms2.playlist == NULL) {
257 ptr->xmms2.playlist = malloc(TEXT_BUFFER_SIZE);
258 ptr->xmms2.playlist[0] = '\0';
261 if (!xmmsc_result_get_string(res, &ptr->xmms2.playlist)) {
262 ptr->xmms2.playlist[0] = '\0';
269 struct information *current_info = &info;
271 /* initialize connection */
272 if (current_info->xmms2_conn_state == CONN_INIT) {
274 if (current_info->xmms2_conn == NULL) {
275 current_info->xmms2_conn = xmmsc_init("conky");
279 if (current_info->xmms2_conn == NULL) {
280 fprintf(stderr, "Conky: xmms2 init failed. %s\n",
281 xmmsc_get_last_error(current_info->xmms2_conn));
286 /* init ok but not connected yet.. */
287 current_info->xmms2_conn_state = CONN_NO;
289 /* clear all values */
290 xmms_clear(current_info);
292 /* fprintf(stderr, "Conky: xmms2 init ok.\n");
297 if (current_info->xmms2_conn_state == CONN_NO) {
299 char *path = getenv("XMMS_PATH");
301 if (!xmmsc_connect(current_info->xmms2_conn, path)) {
302 fprintf(stderr, "Conky: xmms2 connection failed. %s\n",
303 xmmsc_get_last_error(current_info->xmms2_conn));
305 current_info->xmms2_conn_state = CONN_NO;
310 xmmsc_disconnect_callback_set(current_info->xmms2_conn, connection_lost,
312 XMMS_CALLBACK_SET(current_info->xmms2_conn,
313 xmmsc_broadcast_playback_current_id, handle_curent_id,
315 XMMS_CALLBACK_SET(current_info->xmms2_conn,
316 xmmsc_signal_playback_playtime, handle_playtime, current_info);
317 XMMS_CALLBACK_SET(current_info->xmms2_conn,
318 xmmsc_broadcast_playback_status, handle_playback_state_change,
320 XMMS_CALLBACK_SET(current_info->xmms2_conn,
321 xmmsc_broadcast_playlist_loaded, handle_playlist_loaded,
324 /* get playback status, current id and active playlist */
325 XMMS_CALLBACK_SET(current_info->xmms2_conn,
326 xmmsc_playback_current_id, handle_curent_id, current_info);
327 XMMS_CALLBACK_SET(current_info->xmms2_conn,
328 xmmsc_playback_status, handle_playback_state_change, current_info);
329 XMMS_CALLBACK_SET(current_info->xmms2_conn,
330 xmmsc_playlist_current_active, handle_playlist_loaded, current_info);
332 /* everything seems to be ok */
333 current_info->xmms2_conn_state = CONN_OK;
335 /* fprintf(stderr, "Conky: xmms2 connected.\n");
339 /* handle callbacks */
340 if (current_info->xmms2_conn_state == CONN_OK) {
341 struct timeval tmout;
346 select(current_info->xmms2_fd + 1, ¤t_info->xmms2_fdset, NULL,
349 xmmsc_io_in_handle(current_info->xmms2_conn);
350 if (xmmsc_io_want_out(current_info->xmms2_conn)) {
351 xmmsc_io_out_handle(current_info->xmms2_conn);