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.decoder == NULL) {
72 ptr->xmms2.decoder = malloc(TEXT_BUFFER_SIZE);
73 ptr->xmms2.decoder[0] = '\0';
76 if (ptr->xmms2.transport == NULL) {
77 ptr->xmms2.transport = malloc(TEXT_BUFFER_SIZE);
78 ptr->xmms2.transport[0] = '\0';
81 if (ptr->xmms2.url == NULL) {
82 ptr->xmms2.url = malloc(TEXT_BUFFER_SIZE);
83 ptr->xmms2.url[0] = '\0';
86 if (ptr->xmms2.date == NULL) {
87 ptr->xmms2.date = malloc(TEXT_BUFFER_SIZE);
88 ptr->xmms2.date[0] = '\0';
92 static void xmms_clear(struct information *ptr)
95 ptr->xmms2.status[0] = '\0';
96 ptr->xmms2.artist[0] = '\0';
97 ptr->xmms2.album[0] = '\0';
98 ptr->xmms2.title[0] = '\0';
99 ptr->xmms2.genre[0] = '\0';
100 ptr->xmms2.comment[0] = '\0';
101 ptr->xmms2.decoder[0] = '\0';
102 ptr->xmms2.transport[0] = '\0';
103 ptr->xmms2.url[0] = '\0';
104 ptr->xmms2.date[0] = '\0';
107 void connection_lost(void *p)
109 struct information *ptr = p;
111 ptr->xmms2_conn_state = CONN_NO;
114 ptr->xmms2.tracknr = 0;
116 ptr->xmms2.bitrate = 0;
117 ptr->xmms2.duration = 0;
118 ptr->xmms2.elapsed = 0;
120 ptr->xmms2.progress = 0;
123 void handle_curent_id(xmmsc_result_t *res, void *p)
126 struct information *ptr = p;
128 if (xmmsc_result_get_uint(res, ¤t_id)) {
130 xmmsc_result_t *res2;
132 res2 = xmmsc_medialib_get_info(ptr->xmms2_conn, current_id);
133 xmmsc_result_wait(res2);
137 ptr->xmms2.id = current_id;
141 xmmsc_result_get_dict_entry_string(res2, "artist", &temp);
143 strncpy(ptr->xmms2.artist, temp, TEXT_BUFFER_SIZE - 1);
145 strncpy(ptr->xmms2.artist, "[Unknown]", TEXT_BUFFER_SIZE - 1);
148 xmmsc_result_get_dict_entry_string(res2, "title", &temp);
150 strncpy(ptr->xmms2.title, temp, TEXT_BUFFER_SIZE - 1);
152 strncpy(ptr->xmms2.title, "[Unknown]", TEXT_BUFFER_SIZE - 1);
155 xmmsc_result_get_dict_entry_string(res2, "album", &temp);
157 strncpy(ptr->xmms2.album, temp, TEXT_BUFFER_SIZE - 1);
159 strncpy(ptr->xmms2.album, "[Unknown]", TEXT_BUFFER_SIZE - 1);
162 xmmsc_result_get_dict_entry_string(res2, "genre", &temp);
165 strncpy(ptr->xmms2.genre, temp, TEXT_BUFFER_SIZE - 1);
167 strncpy(ptr->xmms2.genre, "[Unknown]", TEXT_BUFFER_SIZE - 1);
170 xmmsc_result_get_dict_entry_string(res2, "comment", &temp);
172 strncpy(ptr->xmms2.comment, temp, TEXT_BUFFER_SIZE - 1);
174 strncpy(ptr->xmms2.comment, "", TEXT_BUFFER_SIZE - 1);
177 xmmsc_result_get_dict_entry_string(res2, "decoder", &temp);
179 strncpy(ptr->xmms2.decoder, temp, TEXT_BUFFER_SIZE - 1);
181 strncpy(ptr->xmms2.decoder, "[Unknown]", TEXT_BUFFER_SIZE - 1);
184 xmmsc_result_get_dict_entry_string(res2, "transport", &temp);
186 strncpy(ptr->xmms2.transport, temp, TEXT_BUFFER_SIZE - 1);
188 strncpy(ptr->xmms2.transport, "[Unknown]", TEXT_BUFFER_SIZE - 1);
191 xmmsc_result_get_dict_entry_string(res2, "url", &temp);
193 strncpy(ptr->xmms2.url, temp, TEXT_BUFFER_SIZE - 1);
195 strncpy(ptr->xmms2.url, "[Unknown]", TEXT_BUFFER_SIZE - 1);
198 xmmsc_result_get_dict_entry_string(res2, "date", &temp);
200 strncpy(ptr->xmms2.date, temp, TEXT_BUFFER_SIZE - 1);
202 strncpy(ptr->xmms2.date, "????", TEXT_BUFFER_SIZE - 1);
207 xmmsc_result_get_dict_entry_int(res2, "tracknr", &itemp);
208 ptr->xmms2.tracknr = itemp;
210 xmmsc_result_get_dict_entry_int(res2, "duration", &itemp);
211 ptr->xmms2.duration = itemp;
213 xmmsc_result_get_dict_entry_int(res2, "bitrate", &itemp);
214 ptr->xmms2.bitrate = itemp / 1000;
216 xmmsc_result_get_dict_entry_int(res2, "size", &itemp);
217 ptr->xmms2.size = (float) itemp / 1048576;
219 xmmsc_result_unref(res2);
223 void handle_playtime(xmmsc_result_t *res, void *p)
225 struct information *ptr = p;
226 xmmsc_result_t *res2;
229 if (xmmsc_result_iserror(res)) {
233 if (!xmmsc_result_get_uint(res, &play_time)) {
237 res2 = xmmsc_result_restart(res);
238 xmmsc_result_unref(res2);
240 ptr->xmms2.elapsed = play_time;
241 ptr->xmms2.progress = (float) play_time / ptr->xmms2.duration;
244 void handle_playback_state_change(xmmsc_result_t *res, void *p)
246 struct information *ptr = p;
249 if (xmmsc_result_iserror(res)) {
253 if (!xmmsc_result_get_uint(res, &pb_state)) {
258 case XMMS_PLAYBACK_STATUS_PLAY:
259 strncpy(ptr->xmms2.status, "Playing", TEXT_BUFFER_SIZE - 1);
261 case XMMS_PLAYBACK_STATUS_PAUSE:
262 strncpy(ptr->xmms2.status, "Paused", TEXT_BUFFER_SIZE - 1);
264 case XMMS_PLAYBACK_STATUS_STOP:
265 strncpy(ptr->xmms2.status, "Stopped", TEXT_BUFFER_SIZE - 1);
268 strncpy(ptr->xmms2.status, "Unknown", TEXT_BUFFER_SIZE - 1);
274 struct information *current_info = &info;
276 /* initialize connection */
277 if (current_info->xmms2_conn_state == CONN_INIT) {
279 if (current_info->xmms2_conn == NULL) {
280 current_info->xmms2_conn = xmmsc_init("conky");
284 if (current_info->xmms2_conn == NULL) {
285 fprintf(stderr, "Conky: xmms2 init failed. %s\n",
286 xmmsc_get_last_error(current_info->xmms2_conn));
291 /* init ok but not connected yet.. */
292 current_info->xmms2_conn_state = CONN_NO;
294 /* clear all values */
295 xmms_clear(current_info);
297 current_info->xmms2.tracknr = 0;
298 current_info->xmms2.id = 0;
299 current_info->xmms2.bitrate = 0;
300 current_info->xmms2.duration = 0;
301 current_info->xmms2.elapsed = 0;
302 current_info->xmms2.size = 0;
303 current_info->xmms2.progress = 0;
305 /* fprintf(stderr, "Conky: xmms2 init ok.\n");
310 if (current_info->xmms2_conn_state == CONN_NO) {
312 char *path = getenv("XMMS_PATH");
314 if (!xmmsc_connect(current_info->xmms2_conn, path)) {
315 fprintf(stderr, "Conky: xmms2 connection failed. %s\n",
316 xmmsc_get_last_error(current_info->xmms2_conn));
318 current_info->xmms2_conn_state = CONN_NO;
323 xmmsc_disconnect_callback_set(current_info->xmms2_conn, connection_lost,
325 XMMS_CALLBACK_SET(current_info->xmms2_conn, xmmsc_playback_current_id,
326 handle_curent_id, current_info);
327 XMMS_CALLBACK_SET(current_info->xmms2_conn,
328 xmmsc_broadcast_playback_current_id, handle_curent_id,
330 XMMS_CALLBACK_SET(current_info->xmms2_conn,
331 xmmsc_signal_playback_playtime, handle_playtime, current_info);
332 XMMS_CALLBACK_SET(current_info->xmms2_conn,
333 xmmsc_broadcast_playback_status, handle_playback_state_change,
336 /* get playback status, it wont be broadcasted untill it chages */
337 xmmsc_result_t *res = xmmsc_playback_status(current_info->xmms2_conn);
339 xmmsc_result_wait(res);
340 unsigned int pb_state;
342 xmmsc_result_get_uint(res, &pb_state);
344 case XMMS_PLAYBACK_STATUS_PLAY:
345 strncpy(current_info->xmms2.status, "Playing",
346 TEXT_BUFFER_SIZE - 1);
348 case XMMS_PLAYBACK_STATUS_PAUSE:
349 strncpy(current_info->xmms2.status, "Paused",
350 TEXT_BUFFER_SIZE - 1);
352 case XMMS_PLAYBACK_STATUS_STOP:
353 strncpy(current_info->xmms2.status, "Stopped",
354 TEXT_BUFFER_SIZE - 1);
357 strncpy(current_info->xmms2.status, "Unknown",
358 TEXT_BUFFER_SIZE - 1);
360 xmmsc_result_unref(res);
362 /* everything seems to be ok */
363 current_info->xmms2_conn_state = CONN_OK;
365 /* fprintf(stderr, "Conky: xmms2 connected.\n");
369 /* handle callbacks */
370 if (current_info->xmms2_conn_state == CONN_OK) {
371 struct timeval tmout;
376 select(current_info->xmms2_fd + 1, ¤t_info->xmms2_fdset, NULL,
379 xmmsc_io_in_handle(current_info->xmms2_conn);
380 if (xmmsc_io_want_out(current_info->xmms2_conn)) {
381 xmmsc_io_out_handle(current_info->xmms2_conn);