2 * xmms2.c: xmms2 stuff for Conky
11 #include <xmmsclient/xmmsclient.h>
19 void connection_lost( void *ptr )
21 //struct information * current_info = &info;
22 ((struct information *)ptr)->xmms2_conn_state = CONN_NO;
24 if ( ((struct information *)ptr)->xmms2.status == NULL )
25 ((struct information *)ptr)->xmms2.status = malloc( TEXT_BUFFER_SIZE );
26 strncpy( ((struct information *)ptr)->xmms2.status, "xmms2 not responding", TEXT_BUFFER_SIZE - 1 );
29 if ( ((struct information *)ptr)->xmms2.artist == NULL )
30 ((struct information *)ptr)->xmms2.artist = malloc( TEXT_BUFFER_SIZE );
31 strncpy( ((struct information *)ptr)->xmms2.artist, "", TEXT_BUFFER_SIZE - 1 );
33 if ( ((struct information *)ptr)->xmms2.album == NULL )
34 ((struct information *)ptr)->xmms2.album = malloc( TEXT_BUFFER_SIZE );
35 strncpy( ((struct information *)ptr)->xmms2.album, "", TEXT_BUFFER_SIZE - 1 );
37 if ( ((struct information *)ptr)->xmms2.title == NULL )
38 ((struct information *)ptr)->xmms2.title = malloc( TEXT_BUFFER_SIZE );
39 strncpy( ((struct information *)ptr)->xmms2.title, "", TEXT_BUFFER_SIZE - 1 );
41 if ( ((struct information *)ptr)->xmms2.genre == NULL )
42 ((struct information *)ptr)->xmms2.genre = malloc( TEXT_BUFFER_SIZE );
43 strncpy( ((struct information *)ptr)->xmms2.genre, "", TEXT_BUFFER_SIZE - 1 );
45 if ( ((struct information *)ptr)->xmms2.comment == NULL )
46 ((struct information *)ptr)->xmms2.comment = malloc( TEXT_BUFFER_SIZE );
47 strncpy( ((struct information *)ptr)->xmms2.comment, "", TEXT_BUFFER_SIZE - 1 );
49 if ( ((struct information *)ptr)->xmms2.decoder == NULL )
50 ((struct information *)ptr)->xmms2.decoder = malloc( TEXT_BUFFER_SIZE );
51 strncpy( ((struct information *)ptr)->xmms2.decoder, "", TEXT_BUFFER_SIZE - 1 );
53 if ( ((struct information *)ptr)->xmms2.transport == NULL )
54 ((struct information *)ptr)->xmms2.transport = malloc( TEXT_BUFFER_SIZE );
55 strncpy( ((struct information *)ptr)->xmms2.transport, "", TEXT_BUFFER_SIZE - 1 );
57 if ( ((struct information *)ptr)->xmms2.url == NULL )
58 ((struct information *)ptr)->xmms2.url = malloc( TEXT_BUFFER_SIZE );
59 strncpy( ((struct information *)ptr)->xmms2.url, "", TEXT_BUFFER_SIZE - 1 );
61 if ( ((struct information *)ptr)->xmms2.date == NULL )
62 ((struct information *)ptr)->xmms2.date = malloc( TEXT_BUFFER_SIZE );
63 strncpy( ((struct information *)ptr)->xmms2.date, "", TEXT_BUFFER_SIZE - 1 );
65 ((struct information *)ptr)->xmms2.tracknr = 0;
66 ((struct information *)ptr)->xmms2.id = 0;
67 ((struct information *)ptr)->xmms2.bitrate = 0;
68 ((struct information *)ptr)->xmms2.duration = 0;
69 ((struct information *)ptr)->xmms2.elapsed = 0;
70 ((struct information *)ptr)->xmms2.size = 0;
71 ((struct information *)ptr)->xmms2.progress = 0;
74 void handle_curent_id( xmmsc_result_t *res, void *ptr )
77 if ( xmmsc_result_get_uint( res, ¤t_id ) )
80 res2 = xmmsc_medialib_get_info( ((struct information *)ptr)->xmms2_conn,
83 xmmsc_result_wait ( res2 );
85 /* update song info here */
86 ((struct information *)ptr)->xmms2.id = current_id;
89 xmmsc_result_get_dict_entry_str( res2, "artist", &temp );
91 if ( ((struct information *)ptr)->xmms2.artist == NULL )
92 ((struct information *)ptr)->xmms2.artist = malloc( TEXT_BUFFER_SIZE );
93 strncpy( ((struct information *)ptr)->xmms2.artist, temp, TEXT_BUFFER_SIZE - 1 );
96 xmmsc_result_get_dict_entry_str( res2, "title", &temp );
98 if ( ((struct information *)ptr)->xmms2.title == NULL )
99 ((struct information *)ptr)->xmms2.title = malloc( TEXT_BUFFER_SIZE );
100 strncpy( ((struct information *)ptr)->xmms2.title, temp, TEXT_BUFFER_SIZE - 1 );
103 xmmsc_result_get_dict_entry_str( res2, "album", &temp );
104 if ( temp != NULL ) {
105 if ( ((struct information *)ptr)->xmms2.album == NULL )
106 ((struct information *)ptr)->xmms2.album = malloc( TEXT_BUFFER_SIZE );
107 strncpy( ((struct information *)ptr)->xmms2.album, temp, TEXT_BUFFER_SIZE - 1 );
110 xmmsc_result_get_dict_entry_str( res2, "genre", &temp );
111 if ( temp != NULL ) {
112 if ( ((struct information *)ptr)->xmms2.genre == NULL )
113 ((struct information *)ptr)->xmms2.genre = malloc( TEXT_BUFFER_SIZE );
114 strncpy( ((struct information *)ptr)->xmms2.genre, temp, TEXT_BUFFER_SIZE - 1 );
117 xmmsc_result_get_dict_entry_str( res2, "comment", &temp );
118 if ( temp != NULL ) {
119 if ( ((struct information *)ptr)->xmms2.comment == NULL )
120 ((struct information *)ptr)->xmms2.comment = malloc( TEXT_BUFFER_SIZE );
121 strncpy( ((struct information *)ptr)->xmms2.comment, temp, TEXT_BUFFER_SIZE - 1 );
124 xmmsc_result_get_dict_entry_str( res2, "decoder", &temp );
125 if ( temp != NULL ) {
126 if ( ((struct information *)ptr)->xmms2.decoder == NULL )
127 ((struct information *)ptr)->xmms2.decoder = malloc( TEXT_BUFFER_SIZE );
128 strncpy( ((struct information *)ptr)->xmms2.decoder, temp, TEXT_BUFFER_SIZE - 1 );
131 xmmsc_result_get_dict_entry_str( res2, "transport", &temp );
132 if ( temp != NULL ) {
133 if ( ((struct information *)ptr)->xmms2.transport == NULL )
134 ((struct information *)ptr)->xmms2.transport = malloc( TEXT_BUFFER_SIZE );
135 strncpy( ((struct information *)ptr)->xmms2.transport, temp, TEXT_BUFFER_SIZE - 1 );
138 xmmsc_result_get_dict_entry_str( res2, "url", &temp );
139 if ( temp != NULL ) {
140 if ( ((struct information *)ptr)->xmms2.url == NULL )
141 ((struct information *)ptr)->xmms2.url = malloc( TEXT_BUFFER_SIZE );
142 strncpy( ((struct information *)ptr)->xmms2.url, temp, TEXT_BUFFER_SIZE - 1 );
145 xmmsc_result_get_dict_entry_str( res2, "date", &temp );
146 if ( temp != NULL ) {
147 if ( ((struct information *)ptr)->xmms2.date == NULL )
148 ((struct information *)ptr)->xmms2.date = malloc( TEXT_BUFFER_SIZE );
149 strncpy( ((struct information *)ptr)->xmms2.date, temp, TEXT_BUFFER_SIZE - 1 );
153 xmmsc_result_get_dict_entry_int32( res2, "tracknr", &itemp );
154 ((struct information *)ptr)->xmms2.tracknr = itemp;
156 xmmsc_result_get_dict_entry_int32( res2, "duration", &itemp );
157 ((struct information *)ptr)->xmms2.duration = itemp;
159 xmmsc_result_get_dict_entry_int32( res2, "bitrate", &itemp );
160 ((struct information *)ptr)->xmms2.bitrate = itemp / 1000;
162 xmmsc_result_get_dict_entry_int32( res2, "size", &itemp );
163 ((struct information *)ptr)->xmms2.size = (float)itemp / 1048576;
165 xmmsc_result_unref( res2 );
169 void handle_playtime( xmmsc_result_t *res, void *ptr )
171 xmmsc_result_t * res2;
174 if ( xmmsc_result_iserror( res ) )
177 if ( !xmmsc_result_get_uint( res, &play_time ) )
180 res2 = xmmsc_result_restart( res );
181 xmmsc_result_unref( res2 );
183 ((struct information *)ptr)->xmms2.elapsed = play_time;
184 ((struct information *)ptr)->xmms2.progress = (float) play_time / ((struct information *)ptr)->xmms2.duration;
187 void handle_playback_state_change( xmmsc_result_t *res, void *ptr )
190 if ( xmmsc_result_iserror( res ) )
193 if ( !xmmsc_result_get_uint( res, &pb_state ) )
196 if ( ((struct information *)ptr)->xmms2.status == NULL )
197 ((struct information *)ptr)->xmms2.status = malloc( TEXT_BUFFER_SIZE );
201 case XMMS_PLAYBACK_STATUS_PLAY:
202 strncpy( ((struct information *)ptr)->xmms2.status,
203 "Playing", TEXT_BUFFER_SIZE - 1 );
205 case XMMS_PLAYBACK_STATUS_PAUSE:
206 strncpy( ((struct information *)ptr)->xmms2.status,
207 "Paused", TEXT_BUFFER_SIZE - 1 );
209 case XMMS_PLAYBACK_STATUS_STOP:
210 strncpy( ((struct information *)ptr)->xmms2.status,
211 "Stopped", TEXT_BUFFER_SIZE - 1 );
214 strncpy( ((struct information *)ptr)->xmms2.status,
215 "Unknown", TEXT_BUFFER_SIZE - 1 );
222 struct information * current_info = &info;
224 /* initialize connection */
225 if ( current_info->xmms2_conn_state == CONN_INIT ) {
227 if ( current_info->xmms2_conn == NULL ) {
228 current_info->xmms2_conn = xmmsc_init( "conky" );
232 if ( current_info->xmms2_conn == NULL ) {
233 fprintf(stderr,"Conky: xmms2 init failed. %s\n",
234 xmmsc_get_last_error ( current_info->xmms2_conn ));
239 /* init ok but not connected yet.. */
240 current_info->xmms2_conn_state = CONN_NO;
242 /* clear all values */
243 if ( current_info->xmms2.artist == NULL )
244 current_info->xmms2.artist = malloc( TEXT_BUFFER_SIZE );
245 strncpy( current_info->xmms2.artist, "", TEXT_BUFFER_SIZE - 1 );
247 if ( current_info->xmms2.album == NULL )
248 current_info->xmms2.album = malloc( TEXT_BUFFER_SIZE );
249 strncpy( current_info->xmms2.album, "", TEXT_BUFFER_SIZE - 1 );
251 if ( current_info->xmms2.title == NULL )
252 current_info->xmms2.title = malloc( TEXT_BUFFER_SIZE );
253 strncpy( current_info->xmms2.title, "", TEXT_BUFFER_SIZE - 1 );
255 if ( current_info->xmms2.genre == NULL )
256 current_info->xmms2.genre = malloc( TEXT_BUFFER_SIZE );
257 strncpy( current_info->xmms2.genre, "", TEXT_BUFFER_SIZE - 1 );
259 if ( current_info->xmms2.comment == NULL )
260 current_info->xmms2.comment = malloc( TEXT_BUFFER_SIZE );
261 strncpy( current_info->xmms2.comment, "", TEXT_BUFFER_SIZE - 1 );
263 if ( current_info->xmms2.decoder == NULL )
264 current_info->xmms2.decoder = malloc( TEXT_BUFFER_SIZE );
265 strncpy( current_info->xmms2.decoder, "", TEXT_BUFFER_SIZE - 1 );
267 if ( current_info->xmms2.transport == NULL )
268 current_info->xmms2.transport = malloc( TEXT_BUFFER_SIZE );
269 strncpy( current_info->xmms2.transport, "", TEXT_BUFFER_SIZE - 1 );
271 if ( current_info->xmms2.url == NULL )
272 current_info->xmms2.url = malloc( TEXT_BUFFER_SIZE );
273 strncpy( current_info->xmms2.url, "", TEXT_BUFFER_SIZE - 1 );
275 if ( current_info->xmms2.date == NULL )
276 current_info->xmms2.date = malloc( TEXT_BUFFER_SIZE );
277 strncpy( current_info->xmms2.date, "", TEXT_BUFFER_SIZE - 1 );
280 current_info->xmms2.tracknr = 0;
281 current_info->xmms2.id = 0;
282 current_info->xmms2.bitrate = 0;
283 current_info->xmms2.duration = 0;
284 current_info->xmms2.elapsed = 0;
285 current_info->xmms2.size = 0;
286 current_info->xmms2.progress = 0;
288 /* fprintf(stderr,"Conky: xmms2 init ok.\n");
293 if ( current_info->xmms2_conn_state == CONN_NO ) {
295 char *path = getenv ( "XMMS_PATH" );
296 if ( !xmmsc_connect( current_info->xmms2_conn, path ) )
298 fprintf(stderr,"Conky: xmms2 connection failed. %s\n",
299 xmmsc_get_last_error ( current_info->xmms2_conn ));
301 current_info->xmms2_conn_state = CONN_NO;
306 xmmsc_disconnect_callback_set( current_info->xmms2_conn, connection_lost, current_info );
307 XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_playback_current_id, handle_curent_id, current_info );
308 XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_broadcast_playback_current_id, handle_curent_id, current_info );
309 XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_signal_playback_playtime, handle_playtime, current_info );
310 XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_broadcast_playback_status, handle_playback_state_change, current_info );
312 // xmmsc_io_need_out_callback_set(current_info->xmms2_conn, io_need_out_callback, NULL);
313 current_info->xmms2_fd = xmmsc_io_fd_get( current_info->xmms2_conn );
314 FD_SET( current_info->xmms2_fd, ¤t_info->xmms2_fdset );
315 if ( !current_info->xmms2_fd )
317 /* fprintf(stderr,"Conky: xmms2 cb init failed. %s\n",
318 xmmsc_get_last_error ( current_info->xmms2_conn ));*/
320 current_info->xmms2_conn_state = CONN_NO;
324 /* get playback state.. it wont be broadcasted by xmms2d unless it changes */
325 xmmsc_result_t * res = xmmsc_playback_status( current_info->xmms2_conn );
326 xmmsc_result_wait ( res );
327 unsigned int pb_state;
329 if ( current_info->xmms2.status == NULL )
330 current_info->xmms2.status = malloc( TEXT_BUFFER_SIZE );
332 xmmsc_result_get_uint( res, &pb_state );
335 case XMMS_PLAYBACK_STATUS_PLAY:
336 strncpy( current_info->xmms2.status,
337 "Playing", TEXT_BUFFER_SIZE - 1 );
339 case XMMS_PLAYBACK_STATUS_PAUSE:
340 strncpy( current_info->xmms2.status,
341 "Paused", TEXT_BUFFER_SIZE - 1 );
343 case XMMS_PLAYBACK_STATUS_STOP:
344 strncpy( current_info->xmms2.status,
345 "Stopped", TEXT_BUFFER_SIZE - 1 );
348 strncpy( current_info->xmms2.status,
349 "Unknown", TEXT_BUFFER_SIZE - 1 );
351 xmmsc_result_unref ( res );
353 /* everything seems to be ok */
354 current_info->xmms2_conn_state = CONN_OK;
356 /* fprintf(stderr,"Conky: xmms2 connected.\n");
361 /* handle callbacks */
362 if ( current_info->xmms2_conn_state == CONN_OK ) {
363 struct timeval tmout;
368 select( current_info->xmms2_fd + 1,
369 ¤t_info->xmms2_fdset, NULL, NULL, &tmout );
371 xmmsc_io_in_handle(current_info->xmms2_conn);
372 if (xmmsc_io_want_out(current_info->xmms2_conn)) {
373 xmmsc_io_out_handle(current_info->xmms2_conn);