1 /*
2 * $Id: mpc.c,v 1.5 2004/03/17 23:19:21 kalle Exp $
3 *
4 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <time.h>
10 #include <string.h>
11 #include <glib.h>
13 #include "config.h"
14 #include "support.h"
15 #include "libmpdclient.h"
16 #include "mpc.h"
17 #include "options.h"
19 #define MAX_SONG_LENGTH 1024
21 void
22 mpc_update_song(mpd_client_t *c)
23 {
24 mpd_InfoEntity *entity;
26 if( mpc_error(c) )
27 return;
29 if( c->song )
30 {
31 mpd_freeSong(c->song);
32 c->song = NULL;
33 }
35 mpd_sendPlaylistInfoCommand(c->connection, c->status->song);
36 if( mpc_error(c) )
37 return;
38 while( (entity=mpd_getNextInfoEntity(c->connection)) )
39 {
40 mpd_Song *song = entity->info.song;
42 if(c->connection->error)
43 {
44 fprintf(stderr,"error: %s\n",c->connection->errorStr);
45 exit(EXIT_FAILURE);
46 }
47 if(entity->type!=MPD_INFO_ENTITY_TYPE_SONG) {
48 mpd_freeInfoEntity(entity);
49 fprintf(stderr,
50 "error: type != MPD_INFO_ENTITY_TYPE_SONG [%d]\n",
51 entity->type);
52 exit(EXIT_FAILURE);
53 }
54 c->song = mpd_songDup(song);
55 mpd_freeInfoEntity(entity);
56 }
57 }
59 int
60 mpc_close(mpd_client_t *c)
61 {
62 if( c->connection )
63 mpd_closeConnection(c->connection);
64 if( c->cwd )
65 free( c->cwd );
67 return 0;
68 }
70 mpd_client_t *
71 mpc_connect(char *host, int port)
72 {
73 mpd_Connection *connection;
74 mpd_client_t *c;
76 connection = mpd_newConnection(host, port, 10);
77 if( connection==NULL )
78 {
79 fprintf(stderr, "mpd_newConnection to %s:%d failed!\n", host, port);
80 exit(EXIT_FAILURE);
81 }
83 c = malloc(sizeof(mpd_client_t));
84 memset(c, 0, sizeof(mpd_client_t));
85 c->connection = connection;
86 c->cwd = strdup("");
88 return c;
89 }
91 int
92 mpc_reconnect(mpd_client_t *c, char *host, int port)
93 {
94 mpd_Connection *connection;
96 connection = mpd_newConnection(host, port, 10);
97 if( connection==NULL )
98 return -1;
99 if( connection->error )
100 {
101 mpd_closeConnection(connection);
102 return -1;
103 }
105 c->connection = connection;
107 return 0;
108 }
111 int
112 mpc_error(mpd_client_t *c)
113 {
114 if( c == NULL || c->connection == NULL )
115 return 1;
116 if( c->connection->error )
117 return 1;
119 return 0;
120 }
122 char *
123 mpc_error_str(mpd_client_t *c)
124 {
125 if( c == NULL || c->connection == NULL )
126 return "Not connected";
128 if( c->connection && c->connection->errorStr )
129 return c->connection->errorStr;
131 return NULL;
132 }
136 int
137 mpc_free_playlist(mpd_client_t *c)
138 {
139 GList *list;
141 if( c==NULL || c->playlist==NULL )
142 return -1;
144 list=g_list_first(c->playlist);
146 while( list!=NULL )
147 {
148 mpd_Song *song = (mpd_Song *) list->data;
150 mpd_freeSong(song);
151 list=list->next;
152 }
153 g_list_free(c->playlist);
154 c->playlist=NULL;
155 c->playlist_length=0;
157 return 0;
158 }
160 int
161 mpc_update_playlist(mpd_client_t *c)
162 {
163 mpd_InfoEntity *entity;
165 // fprintf(stderr, "mpc_update_playlist(): status->playlist = %d\n", c->status->playlist);
167 if( mpc_error(c) )
168 return -1;
170 if( c->playlist )
171 mpc_free_playlist(c);
173 c->playlist_length=0;
174 mpd_sendPlaylistInfoCommand(c->connection,-1);
175 if( mpc_error(c) )
176 return -1;
177 while( (entity=mpd_getNextInfoEntity(c->connection)) )
178 {
179 if(entity->type==MPD_INFO_ENTITY_TYPE_SONG)
180 {
181 mpd_Song *song = mpd_songDup(entity->info.song);
183 c->playlist = g_list_append(c->playlist, (gpointer) song);
184 c->playlist_length++;
185 }
186 mpd_freeInfoEntity(entity);
187 }
188 c->playlist_id = c->status->playlist;
189 c->playlist_updated = 1;
190 c->song_id = -1;
192 return 0;
193 }
195 int
196 mpc_playlist_get_song_index(mpd_client_t *c, char *filename)
197 {
198 GList *list = c->playlist;
199 int i=0;
201 while( list )
202 {
203 mpd_Song *song = (mpd_Song *) list->data;
204 if( strcmp(song->file, filename ) == 0 )
205 return i;
206 list=list->next;
207 i++;
208 }
209 return -1;
210 }
212 mpd_Song *
213 mpc_playlist_get_song(mpd_client_t *c, int n)
214 {
215 return (mpd_Song *) g_list_nth_data(c->playlist, n);
216 }
218 char *
219 mpc_get_song_name(mpd_Song *song)
220 {
221 static char buf[MAX_SONG_LENGTH];
222 char *name;
224 if( song->title )
225 {
226 if( song->artist )
227 {
228 snprintf(buf, MAX_SONG_LENGTH, "%s - %s", song->artist, song->title);
229 name = utf8_to_locale(buf);
230 strncpy(buf, name, MAX_SONG_LENGTH);
231 free(name);
232 return buf;
233 }
234 else
235 {
236 name = utf8_to_locale(song->title);
237 strncpy(buf, name, MAX_SONG_LENGTH);
238 free(name);
239 return buf;
240 }
241 }
242 name = utf8_to_locale(basename(song->file));
243 strncpy(buf, name, MAX_SONG_LENGTH);
244 free(name);
245 return buf;
246 }
248 int
249 mpc_update(mpd_client_t *c)
250 {
251 if( mpc_error(c) )
252 return -1;
254 if( c->status )
255 {
256 mpd_freeStatus(c->status);
257 }
259 c->status = mpd_getStatus(c->connection);
260 if( mpc_error(c) )
261 return -1;
263 if( c->playlist_id!=c->status->playlist )
264 mpc_update_playlist(c);
266 if( c->status->song != c->song_id )
267 {
268 c->song = mpc_playlist_get_song(c, c->status->song);
269 c->song_id = c->status->song;
270 c->song_updated = 1;
271 }
273 return 0;
274 }
281 int
282 mpc_free_filelist(mpd_client_t *c)
283 {
284 GList *list;
286 if( c==NULL || c->filelist==NULL )
287 return -1;
289 list=g_list_first(c->filelist);
291 while( list!=NULL )
292 {
293 filelist_entry_t *entry = list->data;
295 if( entry->entity )
296 mpd_freeInfoEntity(entry->entity);
297 free(entry);
298 list=list->next;
299 }
300 g_list_free(c->filelist);
301 c->filelist=NULL;
302 c->filelist_length=0;
304 return 0;
305 }
309 int
310 mpc_update_filelist(mpd_client_t *c)
311 {
312 mpd_InfoEntity *entity;
314 if( mpc_error(c) )
315 return -1;
317 if( c->filelist )
318 mpc_free_filelist(c);
320 c->filelist_length=0;
322 // mpd_sendListallCommand(conn,"");
323 mpd_sendLsInfoCommand(c->connection, c->cwd);
325 if( c->cwd && c->cwd[0] )
326 {
327 /* add a dummy entry for ./.. */
328 filelist_entry_t *entry = malloc(sizeof(filelist_entry_t));
329 memset(entry, 0, sizeof(filelist_entry_t));
330 entry->entity = NULL;
331 c->filelist = g_list_append(c->filelist, (gpointer) entry);
332 c->filelist_length++;
333 }
335 while( (entity=mpd_getNextInfoEntity(c->connection)) )
336 {
337 filelist_entry_t *entry = malloc(sizeof(filelist_entry_t));
339 memset(entry, 0, sizeof(filelist_entry_t));
340 entry->entity = entity;
341 c->filelist = g_list_append(c->filelist, (gpointer) entry);
342 c->filelist_length++;
343 }
345 c->filelist_updated = 1;
347 mpd_finishCommand(c->connection);
349 mpc_filelist_set_selected(c);
351 return 0;
352 }
354 int
355 mpc_filelist_set_selected(mpd_client_t *c)
356 {
357 GList *list = c->filelist;
359 while( list )
360 {
361 filelist_entry_t *entry = list->data;
362 mpd_InfoEntity *entity = entry->entity ;
364 if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG )
365 {
366 mpd_Song *song = entity->info.song;
368 if( mpc_playlist_get_song_index(c, song->file) >= 0 )
369 entry->selected = 1;
370 else
371 entry->selected = 0;
372 }
374 list=list->next;
375 }
376 return 0;
377 }