1 /* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
2 * vim: ts=4 sw=4 noet ai cindent syntax=c
4 * Conky, a system monitor, based on torsmo
6 * Any original torsmo code is licensed under the BSD license
8 * All code written since the fork of torsmo is licensed under the GPL
10 * Please see COPYING for details
12 * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
14 * All rights reserved.
16 * This program is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 xmmsc_connection_t *xmms2_conn;
38 static void xmms_alloc(struct information *ptr)
41 if (ptr->xmms2.artist == NULL) {
42 ptr->xmms2.artist = malloc(text_buffer_size);
45 if (ptr->xmms2.album == NULL) {
46 ptr->xmms2.album = malloc(text_buffer_size);
49 if (ptr->xmms2.title == NULL) {
50 ptr->xmms2.title = malloc(text_buffer_size);
53 if (ptr->xmms2.genre == NULL) {
54 ptr->xmms2.genre = malloc(text_buffer_size);
57 if (ptr->xmms2.comment == NULL) {
58 ptr->xmms2.comment = malloc(text_buffer_size);
61 if (ptr->xmms2.url == NULL) {
62 ptr->xmms2.url = malloc(text_buffer_size);
65 if (ptr->xmms2.date == NULL) {
66 ptr->xmms2.date = malloc(text_buffer_size);
69 ptr->xmms2.artist[0] = '\0';
70 ptr->xmms2.album[0] = '\0';
71 ptr->xmms2.title[0] = '\0';
72 ptr->xmms2.genre[0] = '\0';
73 ptr->xmms2.comment[0] = '\0';
74 ptr->xmms2.url[0] = '\0';
75 ptr->xmms2.date[0] = '\0';
77 ptr->xmms2.tracknr = 0;
79 ptr->xmms2.bitrate = 0;
80 ptr->xmms2.duration = 0;
81 ptr->xmms2.elapsed = 0;
83 ptr->xmms2.progress = 0;
84 ptr->xmms2.timesplayed = -1;
87 void connection_lost(void *p)
89 struct information *ptr = p;
90 ptr->xmms2.conn_state = CONN_NO;
92 fprintf(stderr,"XMMS2 connection failed. %s\n", xmmsc_get_last_error(xmms2_conn));
95 strncpy(ptr->xmms2.status, "Disocnnected", text_buffer_size - 1);
96 ptr->xmms2.playlist[0] = '\0';
101 int handle_curent_id(xmmsv_t *value, void *p)
103 struct information *ptr = p;
104 xmmsv_t *val, *infos, *dict_entry;
113 if (xmmsv_get_error(value, &errbuf)) {
114 fprintf(stderr,"XMMS2 server error. %s\n", errbuf);
118 if (xmmsv_get_int(value, ¤t_id) && current_id > 0) {
120 res = xmmsc_medialib_get_info(xmms2_conn, current_id);
121 xmmsc_result_wait(res);
122 val = xmmsc_result_get_value(res);
124 if (xmmsv_get_error(val, &errbuf)) {
125 fprintf(stderr,"XMMS2 server error. %s\n", errbuf);
132 ptr->xmms2.id = current_id;
134 infos = xmmsv_propdict_to_dict(val, NULL);
136 if (xmmsv_dict_get(infos, "artist", &dict_entry) && xmmsv_get_string(dict_entry, &charval))
137 strncpy(ptr->xmms2.artist, charval, text_buffer_size - 1);
139 if (xmmsv_dict_get(infos, "title", &dict_entry) && xmmsv_get_string(dict_entry, &charval))
140 strncpy(ptr->xmms2.title, charval, text_buffer_size - 1);
142 if (xmmsv_dict_get(infos, "album", &dict_entry) && xmmsv_get_string(dict_entry, &charval))
143 strncpy(ptr->xmms2.album, charval, text_buffer_size - 1);
145 if (xmmsv_dict_get(infos, "genre", &dict_entry) && xmmsv_get_string(dict_entry, &charval))
146 strncpy(ptr->xmms2.genre, charval, text_buffer_size - 1);
148 if (xmmsv_dict_get(infos, "comment", &dict_entry) && xmmsv_get_string(dict_entry, &charval))
149 strncpy(ptr->xmms2.comment, charval, text_buffer_size - 1);
151 if (xmmsv_dict_get(infos, "url", &dict_entry) && xmmsv_get_string(dict_entry, &charval))
152 strncpy(ptr->xmms2.url, charval, text_buffer_size - 1);
154 if (xmmsv_dict_get(infos, "date", &dict_entry) && xmmsv_get_string(dict_entry, &charval))
155 strncpy(ptr->xmms2.date, charval, text_buffer_size - 1);
159 if (xmmsv_dict_get(infos, "tracknr", &dict_entry) && xmmsv_get_int(dict_entry, &intval))
160 ptr->xmms2.tracknr = intval;
162 if (xmmsv_dict_get(infos, "duration", &dict_entry) && xmmsv_get_int(dict_entry, &intval))
163 ptr->xmms2.duration = intval;
165 if (xmmsv_dict_get(infos, "bitrate", &dict_entry) && xmmsv_get_int(dict_entry, &intval))
166 ptr->xmms2.bitrate = intval / 1000;
168 if (xmmsv_dict_get(infos, "size", &dict_entry) && xmmsv_get_int(dict_entry, &intval))
169 ptr->xmms2.size = (float) intval / 1048576;
171 if (xmmsv_dict_get(infos, "timesplayed", &dict_entry) && xmmsv_get_int(dict_entry, &intval))
172 ptr->xmms2.timesplayed = intval;
176 xmmsc_result_unref(res);
181 int handle_playtime(xmmsv_t *value, void *p)
183 struct information *ptr = p;
187 if (xmmsv_get_error(value, &errbuf)) {
188 fprintf(stderr,"XMMS2 server error. %s\n", errbuf);
192 if (xmmsv_get_int(value, &play_time)) {
193 ptr->xmms2.elapsed = play_time;
194 ptr->xmms2.progress = (float) play_time / ptr->xmms2.duration;
200 int handle_playback_state_change(xmmsv_t *value, void *p)
202 struct information *ptr = p;
206 if (xmmsv_get_error(value, &errbuf)) {
207 fprintf(stderr,"XMMS2 server error. %s\n", errbuf);
211 if (ptr->xmms2.status == NULL) {
212 ptr->xmms2.status = malloc(text_buffer_size);
213 ptr->xmms2.status[0] = '\0';
216 if (xmmsv_get_int(value, &pb_state)) {
218 case XMMS_PLAYBACK_STATUS_PLAY:
219 strncpy(ptr->xmms2.status, "Playing", text_buffer_size - 1);
221 case XMMS_PLAYBACK_STATUS_PAUSE:
222 strncpy(ptr->xmms2.status, "Paused", text_buffer_size - 1);
224 case XMMS_PLAYBACK_STATUS_STOP:
225 strncpy(ptr->xmms2.status, "Stopped", text_buffer_size - 1);
226 ptr->xmms2.elapsed = ptr->xmms2.progress = ptr->xmms2.percent = 0;
229 strncpy(ptr->xmms2.status, "Unknown", text_buffer_size - 1);
235 int handle_playlist_loaded(xmmsv_t *value, void *p)
237 struct information *ptr = p;
238 const char *c, *errbuf;
240 if (xmmsv_get_error(value, &errbuf)) {
241 fprintf(stderr,"XMMS2 server error. %s\n", errbuf);
245 if (ptr->xmms2.playlist == NULL) {
246 ptr->xmms2.playlist = malloc(text_buffer_size);
247 ptr->xmms2.playlist[0] = '\0';
250 if (xmmsv_get_string(value, &c)) {
251 strncpy(ptr->xmms2.playlist, c, text_buffer_size - 1);
256 int update_xmms2(void)
258 struct information *current_info = &info;
260 /* initialize connection */
261 if (current_info->xmms2.conn_state == CONN_INIT) {
263 if (xmms2_conn == NULL) {
264 xmms2_conn = xmmsc_init(PACKAGE);
268 if (xmms2_conn == NULL) {
269 fprintf(stderr,"XMMS2 init failed. %s\n", xmmsc_get_last_error(xmms2_conn));
273 /* init ok but not connected yet.. */
274 current_info->xmms2.conn_state = CONN_NO;
276 /* clear all values */
277 xmms_alloc(current_info);
281 if (current_info->xmms2.conn_state == CONN_NO) {
283 char *path = getenv("XMMS_PATH");
285 if (!xmmsc_connect(xmms2_conn, path)) {
286 fprintf(stderr,"XMMS2 connection failed. %s\n", xmmsc_get_last_error(xmms2_conn));
287 current_info->xmms2.conn_state = CONN_NO;
292 xmmsc_disconnect_callback_set(xmms2_conn, connection_lost, current_info);
293 XMMS_CALLBACK_SET(xmms2_conn, xmmsc_broadcast_playback_current_id,
294 handle_curent_id, current_info);
295 XMMS_CALLBACK_SET(xmms2_conn, xmmsc_signal_playback_playtime,
296 handle_playtime, current_info);
297 XMMS_CALLBACK_SET(xmms2_conn, xmmsc_broadcast_playback_status,
298 handle_playback_state_change, current_info);
299 XMMS_CALLBACK_SET(xmms2_conn, xmmsc_broadcast_playlist_loaded,
300 handle_playlist_loaded, current_info);
302 /* get playback status, current id and active playlist */
303 XMMS_CALLBACK_SET(xmms2_conn, xmmsc_playback_current_id,
304 handle_curent_id, current_info);
305 XMMS_CALLBACK_SET(xmms2_conn, xmmsc_playback_status,
306 handle_playback_state_change, current_info);
307 XMMS_CALLBACK_SET(xmms2_conn, xmmsc_playlist_current_active,
308 handle_playlist_loaded, current_info);
310 /* everything seems to be ok */
311 current_info->xmms2.conn_state = CONN_OK;
314 /* handle callbacks */
315 if (current_info->xmms2.conn_state == CONN_OK) {
317 xmmsc_io_in_handle(xmms2_conn);
318 if (xmmsc_io_want_out(xmms2_conn))
319 xmmsc_io_out_handle(xmms2_conn);