2 * xmms2.c: xmms2 stuff for Conky
11 #include <xmmsclient/xmmsclient.h>
19 static void xmms_alloc(struct information *ptr)
21 if (ptr->xmms2.status == NULL) {
22 ptr->xmms2.status = malloc(TEXT_BUFFER_SIZE);
23 ptr->xmms2.status[0] = '\0';
26 if (ptr->xmms2.artist == NULL) {
27 ptr->xmms2.artist = malloc(TEXT_BUFFER_SIZE);
28 ptr->xmms2.artist[0] = '\0';
31 if (ptr->xmms2.album == NULL) {
32 ptr->xmms2.album = malloc(TEXT_BUFFER_SIZE);
33 ptr->xmms2.album[0] = '\0';
36 if (ptr->xmms2.title == NULL) {
37 ptr->xmms2.title = malloc(TEXT_BUFFER_SIZE);
38 ptr->xmms2.title[0] = '\0';
41 if (ptr->xmms2.genre == NULL) {
42 ptr->xmms2.genre = malloc(TEXT_BUFFER_SIZE);
43 ptr->xmms2.genre[0] = '\0';
46 if (ptr->xmms2.comment == NULL) {
47 ptr->xmms2.comment = malloc(TEXT_BUFFER_SIZE);
48 ptr->xmms2.comment[0] = '\0';
51 if (ptr->xmms2.decoder == NULL) {
52 ptr->xmms2.decoder = malloc(TEXT_BUFFER_SIZE);
53 ptr->xmms2.decoder[0] = '\0';
56 if (ptr->xmms2.transport == NULL) {
57 ptr->xmms2.transport = malloc(TEXT_BUFFER_SIZE);
58 ptr->xmms2.transport[0] = '\0';
61 if (ptr->xmms2.url == NULL) {
62 ptr->xmms2.url = malloc(TEXT_BUFFER_SIZE);
63 ptr->xmms2.url[0] = '\0';
66 if (ptr->xmms2.date == NULL) {
67 ptr->xmms2.date = malloc(TEXT_BUFFER_SIZE);
68 ptr->xmms2.date[0] = '\0';
72 static void xmms_clear(struct information *ptr) {
74 ptr->xmms2.status[0] = '\0';
75 ptr->xmms2.artist[0] = '\0';
76 ptr->xmms2.album[0] = '\0';
77 ptr->xmms2.title[0] = '\0';
78 ptr->xmms2.genre[0] = '\0';
79 ptr->xmms2.comment[0] = '\0';
80 ptr->xmms2.decoder[0] = '\0';
81 ptr->xmms2.transport[0] = '\0';
82 ptr->xmms2.url[0] = '\0';
83 ptr->xmms2.date[0] = '\0';
86 void connection_lost(void *p)
88 struct information *ptr = p;
89 ptr->xmms2_conn_state = CONN_NO;
92 ptr->xmms2.tracknr = 0;
94 ptr->xmms2.bitrate = 0;
95 ptr->xmms2.duration = 0;
96 ptr->xmms2.elapsed = 0;
98 ptr->xmms2.progress = 0;
101 void handle_curent_id(xmmsc_result_t *res, void *p)
104 struct information *ptr = p;
106 if ( xmmsc_result_get_uint( res, ¤t_id ) ) {
108 xmmsc_result_t *res2;
109 res2 = xmmsc_medialib_get_info(ptr->xmms2_conn, current_id);
110 xmmsc_result_wait( res2 );
114 ptr->xmms2.id = current_id;
117 xmmsc_result_get_dict_entry_string( res2, "artist", &temp );
118 if ( temp != NULL ) {
119 strncpy(ptr->xmms2.artist, temp, TEXT_BUFFER_SIZE - 1);
121 strncpy(ptr->xmms2.artist, "[Unknown]", TEXT_BUFFER_SIZE - 1);
125 xmmsc_result_get_dict_entry_string( res2, "title", &temp );
126 if ( temp != NULL ) {
127 strncpy(ptr->xmms2.title, temp, TEXT_BUFFER_SIZE - 1);
129 strncpy(ptr->xmms2.title, "[Unknown]", TEXT_BUFFER_SIZE - 1);
132 xmmsc_result_get_dict_entry_string( res2, "album", &temp );
133 if ( temp != NULL ) {
134 strncpy(ptr->xmms2.album, temp, TEXT_BUFFER_SIZE - 1);
136 strncpy(ptr->xmms2.album, "[Unknown]", TEXT_BUFFER_SIZE - 1);
140 xmmsc_result_get_dict_entry_string( res2, "genre", &temp );
141 if ( temp != NULL ) {
143 strncpy(ptr->xmms2.genre, temp, TEXT_BUFFER_SIZE - 1);
145 strncpy(ptr->xmms2.genre, "[Unknown]", TEXT_BUFFER_SIZE - 1);
149 xmmsc_result_get_dict_entry_string( res2, "comment", &temp );
150 if ( temp != NULL ) {
151 strncpy(ptr->xmms2.comment, temp, TEXT_BUFFER_SIZE - 1);
153 strncpy(ptr->xmms2.comment, "", TEXT_BUFFER_SIZE - 1);
157 xmmsc_result_get_dict_entry_string( res2, "decoder", &temp );
158 if ( temp != NULL ) {
159 strncpy(ptr->xmms2.decoder, temp, TEXT_BUFFER_SIZE - 1);
161 strncpy(ptr->xmms2.decoder, "[Unknown]", TEXT_BUFFER_SIZE - 1);
165 xmmsc_result_get_dict_entry_string( res2, "transport", &temp );
166 if ( temp != NULL ) {
167 strncpy(ptr->xmms2.transport, temp, TEXT_BUFFER_SIZE - 1);
169 strncpy(ptr->xmms2.transport, "[Unknown]", TEXT_BUFFER_SIZE - 1);
173 xmmsc_result_get_dict_entry_string( res2, "url", &temp );
174 if ( temp != NULL ) {
175 strncpy(ptr->xmms2.url, temp, TEXT_BUFFER_SIZE - 1);
177 strncpy(ptr->xmms2.url, "[Unknown]", TEXT_BUFFER_SIZE - 1);
181 xmmsc_result_get_dict_entry_string( res2, "date", &temp );
182 if ( temp != NULL ) {
183 strncpy(ptr->xmms2.date, temp, TEXT_BUFFER_SIZE - 1);
185 strncpy(ptr->xmms2.date, "????", TEXT_BUFFER_SIZE - 1);
190 xmmsc_result_get_dict_entry_int( res2, "tracknr", &itemp );
191 ptr->xmms2.tracknr = itemp;
193 xmmsc_result_get_dict_entry_int( res2, "duration", &itemp );
194 ptr->xmms2.duration = itemp;
196 xmmsc_result_get_dict_entry_int( res2, "bitrate", &itemp );
197 ptr->xmms2.bitrate = itemp / 1000;
199 xmmsc_result_get_dict_entry_int( res2, "size", &itemp );
200 ptr->xmms2.size = (float)itemp / 1048576;
202 xmmsc_result_unref( res2 );
206 void handle_playtime(xmmsc_result_t *res, void *p) {
207 struct information *ptr = p;
208 xmmsc_result_t * res2;
211 if ( xmmsc_result_iserror( res ) )
214 if ( !xmmsc_result_get_uint( res, &play_time ) )
217 res2 = xmmsc_result_restart( res );
218 xmmsc_result_unref( res2 );
220 ptr->xmms2.elapsed = play_time;
221 ptr->xmms2.progress = (float) play_time / ptr->xmms2.duration;
224 void handle_playback_state_change(xmmsc_result_t *res, void *p) {
225 struct information *ptr = p;
227 if ( xmmsc_result_iserror( res ) )
230 if ( !xmmsc_result_get_uint( res, &pb_state ) )
234 case XMMS_PLAYBACK_STATUS_PLAY:
235 strncpy(ptr->xmms2.status, "Playing", TEXT_BUFFER_SIZE - 1);
237 case XMMS_PLAYBACK_STATUS_PAUSE:
238 strncpy(ptr->xmms2.status, "Paused", TEXT_BUFFER_SIZE - 1);
240 case XMMS_PLAYBACK_STATUS_STOP:
241 strncpy(ptr->xmms2.status, "Stopped", TEXT_BUFFER_SIZE - 1);
244 strncpy(ptr->xmms2.status, "Unknown", TEXT_BUFFER_SIZE - 1);
249 void update_xmms2() {
250 struct information * current_info = &info;
252 /* initialize connection */
253 if ( current_info->xmms2_conn_state == CONN_INIT ) {
255 if ( current_info->xmms2_conn == NULL ) {
256 current_info->xmms2_conn = xmmsc_init( "conky" );
260 if ( current_info->xmms2_conn == NULL ) {
261 fprintf(stderr,"Conky: xmms2 init failed. %s\n", xmmsc_get_last_error ( current_info->xmms2_conn ));
266 /* init ok but not connected yet.. */
267 current_info->xmms2_conn_state = CONN_NO;
269 /* clear all values */
270 xmms_clear(current_info);
272 current_info->xmms2.tracknr = 0;
273 current_info->xmms2.id = 0;
274 current_info->xmms2.bitrate = 0;
275 current_info->xmms2.duration = 0;
276 current_info->xmms2.elapsed = 0;
277 current_info->xmms2.size = 0;
278 current_info->xmms2.progress = 0;
280 /* fprintf(stderr,"Conky: xmms2 init ok.\n");
285 if ( current_info->xmms2_conn_state == CONN_NO ) {
287 char *path = getenv ( "XMMS_PATH" );
288 if ( !xmmsc_connect( current_info->xmms2_conn, path ) ) {
289 fprintf(stderr,"Conky: xmms2 connection failed. %s\n",
290 xmmsc_get_last_error ( current_info->xmms2_conn ));
292 current_info->xmms2_conn_state = CONN_NO;
297 xmmsc_disconnect_callback_set( current_info->xmms2_conn, connection_lost, current_info );
298 XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_playback_current_id, handle_curent_id, current_info );
299 XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_broadcast_playback_current_id, handle_curent_id, current_info );
300 XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_signal_playback_playtime, handle_playtime, current_info );
301 XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_broadcast_playback_status, handle_playback_state_change, current_info );
303 /* get playback status, it wont be broadcasted untill it chages */
304 xmmsc_result_t * res = xmmsc_playback_status( current_info->xmms2_conn );
305 xmmsc_result_wait ( res );
306 unsigned int pb_state;
308 xmmsc_result_get_uint( res, &pb_state );
310 case XMMS_PLAYBACK_STATUS_PLAY:
311 strncpy(current_info->xmms2.status,
312 "Playing", TEXT_BUFFER_SIZE - 1 );
314 case XMMS_PLAYBACK_STATUS_PAUSE:
315 strncpy( current_info->xmms2.status,
316 "Paused", TEXT_BUFFER_SIZE - 1 );
318 case XMMS_PLAYBACK_STATUS_STOP:
319 strncpy( current_info->xmms2.status,
320 "Stopped", TEXT_BUFFER_SIZE - 1 );
323 strncpy( current_info->xmms2.status,
324 "Unknown", TEXT_BUFFER_SIZE - 1 );
326 xmmsc_result_unref ( res );
328 /* everything seems to be ok */
329 current_info->xmms2_conn_state = CONN_OK;
331 /* fprintf(stderr,"Conky: xmms2 connected.\n");
336 /* handle callbacks */
337 if ( current_info->xmms2_conn_state == CONN_OK ) {
338 struct timeval tmout;
342 select( current_info->xmms2_fd + 1, ¤t_info->xmms2_fdset, NULL, NULL, &tmout );
344 xmmsc_io_in_handle(current_info->xmms2_conn);
345 if (xmmsc_io_want_out(current_info->xmms2_conn)) {
346 xmmsc_io_out_handle(current_info->xmms2_conn);