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( c->song )
27 {
28 mpd_freeSong(c->song);
29 c->song = NULL;
30 }
32 mpd_sendPlaylistInfoCommand(c->connection, c->status->song);
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 free( c->cwd );
62 return 0;
63 }
65 mpd_client_t *
66 mpc_connect(char *host, int port)
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 = malloc(sizeof(mpd_client_t));
79 memset(c, 0, sizeof(mpd_client_t));
80 c->connection = connection;
81 c->cwd = strdup("");
83 return c;
84 }
86 int
87 mpc_error(mpd_client_t *c)
88 {
89 if( c == NULL || c->connection == NULL )
90 return 1;
91 if( c->connection->error )
92 return 1;
94 return 0;
95 }
97 char *
98 mpc_error_str(mpd_client_t *c)
99 {
100 if( c == NULL || c->connection == NULL )
101 return "Not connected";
103 if( c->connection && c->connection->errorStr )
104 return c->connection->errorStr;
106 return NULL;
107 }
111 int
112 mpc_free_playlist(mpd_client_t *c)
113 {
114 GList *list;
116 if( c==NULL || c->playlist==NULL )
117 return -1;
119 list=g_list_first(c->playlist);
121 while( list!=NULL )
122 {
123 mpd_Song *song = (mpd_Song *) list->data;
125 mpd_freeSong(song);
126 list=list->next;
127 }
128 g_list_free(c->playlist);
129 c->playlist=NULL;
130 c->playlist_length=0;
132 return 0;
133 }
135 int
136 mpc_update_playlist(mpd_client_t *c)
137 {
138 mpd_InfoEntity *entity;
140 // fprintf(stderr, "mpc_update_playlist(): status->playlist = %d\n", c->status->playlist);
142 if( c->playlist )
143 mpc_free_playlist(c);
145 c->playlist_length=0;
146 mpd_sendPlaylistInfoCommand(c->connection,-1);
147 while( (entity=mpd_getNextInfoEntity(c->connection)) )
148 {
149 if(entity->type==MPD_INFO_ENTITY_TYPE_SONG)
150 {
151 mpd_Song *song = mpd_songDup(entity->info.song);
153 c->playlist = g_list_append(c->playlist, (gpointer) song);
154 c->playlist_length++;
155 }
156 mpd_freeInfoEntity(entity);
157 }
158 c->playlist_id = c->status->playlist;
159 c->playlist_updated = 1;
160 c->song_id = -1;
162 return 0;
163 }
165 int
166 mpc_playlist_get_song_index(mpd_client_t *c, char *filename)
167 {
168 GList *list = c->playlist;
169 int i=0;
171 while( list )
172 {
173 mpd_Song *song = (mpd_Song *) list->data;
174 if( strcmp(song->file, filename ) == 0 )
175 return i;
176 list=list->next;
177 i++;
178 }
179 return -1;
180 }
182 mpd_Song *
183 mpc_playlist_get_song(mpd_client_t *c, int n)
184 {
185 return (mpd_Song *) g_list_nth_data(c->playlist, n);
186 }
188 char *
189 mpc_get_song_name(mpd_Song *song)
190 {
191 static char buf[MAX_SONG_LENGTH];
192 char *name;
194 if( song->title )
195 {
196 if( song->artist )
197 {
198 snprintf(buf, MAX_SONG_LENGTH, "%s - %s", song->artist, song->title);
199 name = utf8_to_locale(buf);
200 strncpy(buf, name, MAX_SONG_LENGTH);
201 free(name);
202 return buf;
203 }
204 else
205 {
206 name = utf8_to_locale(song->title);
207 strncpy(buf, name, MAX_SONG_LENGTH);
208 free(name);
209 return buf;
210 }
211 }
212 name = utf8_to_locale(song->file);
213 strncpy(buf, name, MAX_SONG_LENGTH);
214 free(name);
215 return buf;
216 }
218 int
219 mpc_update(mpd_client_t *c)
220 {
221 if( c->status )
222 {
223 mpd_freeStatus(c->status);
224 }
226 c->status = mpd_getStatus(c->connection);
228 // if( c->playlist == NULL || c->playlist_id!=c->status->playlist )
229 if( c->playlist_id!=c->status->playlist )
230 mpc_update_playlist(c);
232 // if( c->song == NULL || c->status->song != c->song_id )
233 if( c->status->song != c->song_id )
234 {
235 c->song = mpc_playlist_get_song(c, c->status->song);
236 c->song_id = c->status->song;
237 c->song_updated = 1;
238 }
240 return 0;
241 }
248 int
249 mpc_free_filelist(mpd_client_t *c)
250 {
251 GList *list;
253 if( c==NULL || c->filelist==NULL )
254 return -1;
256 list=g_list_first(c->filelist);
258 while( list!=NULL )
259 {
260 filelist_entry_t *entry = list->data;
262 if( entry->entity )
263 mpd_freeInfoEntity(entry->entity);
264 free(entry);
265 list=list->next;
266 }
267 g_list_free(c->filelist);
268 c->filelist=NULL;
269 c->filelist_length=0;
271 return 0;
272 }
276 int
277 mpc_update_filelist(mpd_client_t *c)
278 {
279 mpd_InfoEntity *entity;
281 if( c->filelist )
282 mpc_free_filelist(c);
284 c->filelist_length=0;
286 // mpd_sendListallCommand(conn,"");
287 mpd_sendLsInfoCommand(c->connection, c->cwd);
289 if( c->cwd && c->cwd[0] )
290 {
291 /* add a dummy entry for ./.. */
292 filelist_entry_t *entry = malloc(sizeof(filelist_entry_t));
293 memset(entry, 0, sizeof(filelist_entry_t));
294 entry->entity = NULL;
295 c->filelist = g_list_append(c->filelist, (gpointer) entry);
296 c->filelist_length++;
297 }
299 while( (entity=mpd_getNextInfoEntity(c->connection)) )
300 {
301 filelist_entry_t *entry = malloc(sizeof(filelist_entry_t));
303 memset(entry, 0, sizeof(filelist_entry_t));
304 entry->entity = entity;
305 c->filelist = g_list_append(c->filelist, (gpointer) entry);
306 c->filelist_length++;
307 }
309 c->filelist_updated = 1;
311 mpd_finishCommand(c->connection);
313 mpc_filelist_set_selected(c);
315 return 0;
316 }
318 int
319 mpc_filelist_set_selected(mpd_client_t *c)
320 {
321 GList *list = c->filelist;
323 while( list )
324 {
325 filelist_entry_t *entry = list->data;
326 mpd_InfoEntity *entity = entry->entity ;
328 if( entity && entity->type==MPD_INFO_ENTITY_TYPE_SONG )
329 {
330 mpd_Song *song = entity->info.song;
332 if( mpc_playlist_get_song_index(c, song->file) >= 0 )
333 entry->selected = 1;
334 else
335 entry->selected = 0;
336 }
338 list=list->next;
339 }
340 return 0;
341 }