1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <time.h>
5 #include <string.h>
6 #include <glib.h>
8 #include "config.h"
9 #include "support.h"
10 #include "libmpdclient.h"
11 #include "mpc.h"
12 #include "options.h"
14 #define MAX_SONG_LENGTH 1024
16 void
17 mpc_update_song(mpd_client_t *c)
18 {
19 mpd_InfoEntity *entity;
21 if( mpc_error(c) )
22 return;
24 if( c->song )
25 {
26 mpd_freeSong(c->song);
27 c->song = NULL;
28 }
30 mpd_sendPlaylistInfoCommand(c->connection, c->status->song);
31 if( mpc_error(c) )
32 return;
33 while( (entity=mpd_getNextInfoEntity(c->connection)) )
34 {
35 mpd_Song *song = entity->info.song;
37 if(c->connection->error)
38 {
39 fprintf(stderr,"error: %s\n",c->connection->errorStr);
40 exit(EXIT_FAILURE);
41 }
42 if(entity->type!=MPD_INFO_ENTITY_TYPE_SONG) {
43 mpd_freeInfoEntity(entity);
44 fprintf(stderr,
45 "error: type != MPD_INFO_ENTITY_TYPE_SONG [%d]\n",
46 entity->type);
47 exit(EXIT_FAILURE);
48 }
49 c->song = mpd_songDup(song);
50 mpd_freeInfoEntity(entity);
51 }
52 }
54 int
55 mpc_close(mpd_client_t *c)
56 {
57 if( c->connection )
58 mpd_closeConnection(c->connection);
59 if( c->cwd )
60 g_free( c->cwd );
62 return 0;
63 }
65 mpd_client_t *
66 mpc_connect(char *host, int port, char *password)
67 {
68 mpd_Connection *connection;
69 mpd_client_t *c;
71 connection = mpd_newConnection(host, port, 10);
72 if( connection==NULL )
73 {
74 fprintf(stderr, "mpd_newConnection to %s:%d failed!\n", host, port);
75 exit(EXIT_FAILURE);
76 }
78 c = g_malloc(sizeof(mpd_client_t));
79 memset(c, 0, sizeof(mpd_client_t));
80 c->connection = connection;
81 c->cwd = g_strdup("");
83 if( password )
84 {
85 mpd_sendPasswordCommand(connection, password);
86 mpd_finishCommand(connection);
87 }
89 return c;
90 }
92 int
93 mpc_reconnect(mpd_client_t *c, char *host, int port, char *password)
94 {
95 mpd_Connection *connection;
97 connection = mpd_newConnection(host, port, 10);
98 if( connection==NULL )
99 return -1;
100 if( connection->error )
101 {
102 mpd_closeConnection(connection);
103 return -1;
104 }
106 c->connection = connection;
108 if( password )
109 {
110 mpd_sendPasswordCommand(connection, password);
111 mpd_finishCommand(connection);
112 }
114 return 0;
115 }
118 int
119 mpc_error(mpd_client_t *c)
120 {
121 if( c == NULL || c->connection == NULL )
122 return 1;
123 if( c->connection->error )
124 return c->connection->error;
126 return 0;
127 }
129 char *
130 mpc_error_str(mpd_client_t *c)
131 {
132 if( c == NULL || c->connection == NULL )
133 return "Not connected";
135 if( c->connection && c->connection->errorStr )
136 return c->connection->errorStr;
138 return NULL;
139 }
143 int
144 mpc_free_playlist(mpd_client_t *c)
145 {
146 GList *list;
148 if( c==NULL || c->playlist==NULL )
149 return -1;
151 list=g_list_first(c->playlist);
153 while( list!=NULL )
154 {
155 mpd_Song *song = (mpd_Song *) list->data;
157 mpd_freeSong(song);
158 list=list->next;
159 }
160 g_list_free(c->playlist);
161 c->playlist=NULL;
162 c->playlist_length=0;
164 return 0;
165 }
167 int
168 mpc_update_playlist(mpd_client_t *c)
169 {
170 mpd_InfoEntity *entity;
172 // fprintf(stderr, "mpc_update_playlist(): status->playlist = %d\n", c->status->playlist);
174 if( mpc_error(c) )
175 return -1;
177 if( c->playlist )
178 mpc_free_playlist(c);
180 c->playlist_length=0;
181 mpd_sendPlaylistInfoCommand(c->connection,-1);
182 if( mpc_error(c) )
183 return -1;
184 while( (entity=mpd_getNextInfoEntity(c->connection)) )
185 {
186 if(entity->type==MPD_INFO_ENTITY_TYPE_SONG)
187 {
188 mpd_Song *song = mpd_songDup(entity->info.song);
190 c->playlist = g_list_append(c->playlist, (gpointer) song);
191 c->playlist_length++;
192 }
193 mpd_freeInfoEntity(entity);
194 }
195 c->playlist_id = c->status->playlist;
196 c->playlist_updated = 1;
197 c->song_id = -1;
199 return 0;
200 }
202 int
203 mpc_playlist_get_song_index(mpd_client_t *c, char *filename)
204 {
205 GList *list = c->playlist;
206 int i=0;
208 while( list )
209 {
210 mpd_Song *song = (mpd_Song *) list->data;
211 if( strcmp(song->file, filename ) == 0 )
212 return i;
213 list=list->next;
214 i++;
215 }
216 return -1;
217 }
219 mpd_Song *
220 mpc_playlist_get_song(mpd_client_t *c, int n)
221 {
222 return (mpd_Song *) g_list_nth_data(c->playlist, n);
223 }
225 char *
226 mpc_get_song_name(mpd_Song *song)
227 {
228 static char buf[MAX_SONG_LENGTH];
229 char *name;
231 if( song->title )
232 {
233 if( song->artist )
234 {
235 snprintf(buf, MAX_SONG_LENGTH, "%s - %s", song->artist, song->title);
236 name = utf8_to_locale(buf);
237 strncpy(buf, name, MAX_SONG_LENGTH);
238 g_free(name);
239 return buf;
240 }
241 else
242 {
243 name = utf8_to_locale(song->title);
244 strncpy(buf, name, MAX_SONG_LENGTH);
245 g_free(name);
246 return buf;
247 }
248 }
249 name = utf8_to_locale(basename(song->file));
250 strncpy(buf, name, MAX_SONG_LENGTH);
251 g_free(name);
252 return buf;
253 }
255 int
256 mpc_update(mpd_client_t *c)
257 {
258 if( mpc_error(c) )
259 return -1;
261 if( c->status )
262 {
263 mpd_freeStatus(c->status);
264 }
266 c->status = mpd_getStatus(c->connection);
267 if( mpc_error(c) )
268 return -1;
270 if( c->playlist_id!=c->status->playlist )
271 mpc_update_playlist(c);
273 if( c->status->song != c->song_id )
274 {
275 c->song = mpc_playlist_get_song(c, c->status->song);
276 c->song_id = c->status->song;
277 c->song_updated = 1;
278 }
280 return 0;
281 }
288 int
289 mpc_free_filelist(mpd_client_t *c)
290 {
291 GList *list;
293 if( c==NULL || c->filelist==NULL )
294 return -1;
296 list=g_list_first(c->filelist);
298 while( list!=NULL )
299 {
300 filelist_entry_t *entry = list->data;
302 if( entry->entity )
303 mpd_freeInfoEntity(entry->entity);
304 g_free(entry);
305 list=list->next;
306 }
307 g_list_free(c->filelist);
308 c->filelist=NULL;
309 c->filelist_length=0;
311 return 0;
312 }
316 int
317 mpc_update_filelist(mpd_client_t *c)
318 {
319 mpd_InfoEntity *entity;
321 if( mpc_error(c) )
322 return -1;
324 if( c->filelist )
325 mpc_free_filelist(c);
327 c->filelist_length=0;
329 // mpd_sendListallCommand(conn,"");
330 mpd_sendLsInfoCommand(c->connection, c->cwd);
332 if( c->cwd && c->cwd[0] )
333 {
334 /* add a dummy entry for ./.. */
335 filelist_entry_t *entry = g_malloc(sizeof(filelist_entry_t));
336 memset(entry, 0, sizeof(filelist_entry_t));
337 entry->entity = NULL;
338 c->filelist = g_list_append(c->filelist, (gpointer) entry);
339 c->filelist_length++;
340 }
342 while( (entity=mpd_getNextInfoEntity(c->connection)) )
343 {
344 filelist_entry_t *entry = g_malloc(sizeof(filelist_entry_t));
346 memset(entry, 0, sizeof(filelist_entry_t));
347 entry->entity = entity;
348 c->filelist = g_list_append(c->filelist, (gpointer) entry);
349 c->filelist_length++;
350 }
352 c->filelist_updated = 1;
354 mpd_finishCommand(c->connection);
356 mpc_filelist_set_selected(c);
358 return 0;
359 }
361 int
362 mpc_filelist_set_selected(mpd_client_t *c)
363 {
364 GList *list = c->filelist;
366 while( list )
367 {
368 filelist_entry_t *entry = list->data;
369 mpd_InfoEntity *entity = entry->entity ;
371 if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG )
372 {
373 mpd_Song *song = entity->info.song;
375 if( mpc_playlist_get_song_index(c, song->file) >= 0 )
376 entry->selected = 1;
377 else
378 entry->selected = 0;
379 }
381 list=list->next;
382 }
383 return 0;
384 }