Code

Added iconv support
[ncmpc.git] / mpc.c
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 );
61   
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     }
77   
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;
111 int
112 mpc_free_playlist(mpd_client_t *c)
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;
135 int 
136 mpc_update_playlist(mpd_client_t *c)
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;
165 int
166 mpc_playlist_get_song_index(mpd_client_t *c, char *filename)
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;
182 mpd_Song *
183 mpc_playlist_get_song(mpd_client_t *c, int n)
185   return (mpd_Song *) g_list_nth_data(c->playlist, n);
188 char *
189 mpc_get_song_name(mpd_Song *song)
191   static char buf[MAX_SONG_LENGTH];
192   char *name;
193   
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;
218 int 
219 mpc_update(mpd_client_t *c)
221   if( c->status )
222     {
223       mpd_freeStatus(c->status);
224     }
226   c->status = mpd_getStatus(c->connection);
227   
228   //  if( c->playlist == NULL || c->playlist_id!=c->status->playlist )
229   if( c->playlist_id!=c->status->playlist )
230     mpc_update_playlist(c);
231   
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;
248 int
249 mpc_free_filelist(mpd_client_t *c)
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;
276 int 
277 mpc_update_filelist(mpd_client_t *c)
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));
302       
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     }
308   
309   c->filelist_updated = 1;
311   mpd_finishCommand(c->connection);
313   mpc_filelist_set_selected(c);
315   return 0;
318 int 
319 mpc_filelist_set_selected(mpd_client_t *c)
321   GList *list = c->filelist;
323   while( list )
324     {
325       filelist_entry_t *entry = list->data;
326       mpd_InfoEntity *entity = entry->entity ;      
327       
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;