sticky hints
[monky] / src / libmpdclient.h
1 /* libmpdclient
2    (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
3    This project's homepage is: http://www.musicpd.org
4   
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8                                                                                 
9    - Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11                                                                                 
12    - Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15                                                                                 
16    - Neither the name of the Music Player Daemon nor the names of its
17    contributors may be used to endorse or promote products derived from
18    this software without specific prior written permission.
19                                                                                 
20    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31    
32    $Id$
33
34 */
35
36 #ifndef LIBMPDCLIENT_H
37 #define LIBMPDCLIENT_H
38
39 #include <sys/time.h>
40
41 #define MPD_BUFFER_MAX_LENGTH   50000
42 #define MPD_WELCOME_MESSAGE     "OK MPD "
43
44 #define MPD_ERROR_TIMEOUT       10      /* timeout trying to talk to mpd */
45 #define MPD_ERROR_SYSTEM        11      /* system error */
46 #define MPD_ERROR_UNKHOST       12      /* unknown host */
47 #define MPD_ERROR_CONNPORT      13      /* problems connecting to port on host */
48 #define MPD_ERROR_NOTMPD        14      /* mpd not running on port at host */
49 #define MPD_ERROR_NORESPONSE    15      /* no response on attempting to connect */
50 #define MPD_ERROR_SENDING       16      /* error sending command */
51 #define MPD_ERROR_CONNCLOSED    17      /* connection closed by mpd */
52 #define MPD_ERROR_ACK           18      /* ACK returned! */
53 #define MPD_ERROR_BUFFEROVERRUN 19      /* Buffer was overrun! */
54
55 #define MPD_ACK_ERROR_UNK       -1
56 #define MPD_ERROR_AT_UNK        -1
57
58 #define MPD_ACK_ERROR_NOT_LIST                  1
59 #define MPD_ACK_ERROR_ARG                       2
60 #define MPD_ACK_ERROR_PASSWORD                  3
61 #define MPD_ACK_ERROR_PERMISSION                4
62 #define MPD_ACK_ERROR_UNKNOWN_CMD               5
63
64 #define MPD_ACK_ERROR_NO_EXIST                  50
65 #define MPD_ACK_ERROR_PLAYLIST_MAX              51
66 #define MPD_ACK_ERROR_SYSTEM                    52
67 #define MPD_ACK_ERROR_PLAYLIST_LOAD             53
68 #define MPD_ACK_ERROR_UPDATE_ALREADY            54
69 #define MPD_ACK_ERROR_PLAYER_SYNC               55
70 #define MPD_ACK_ERROR_EXIST                     56
71
72 #ifdef __cplusplus
73 extern "C" {
74 #endif
75
76 /* internal stuff don't touch this struct */
77         typedef struct _mpd_ReturnElement {
78                 char *name;
79                 char *value;
80         } mpd_ReturnElement;
81
82 /* mpd_Connection
83  * holds info about connection to mpd
84  * use error, and errorStr to detect errors
85  */
86         typedef struct _mpd_Connection {
87                 /* use this to check the version of mpd */
88                 int version[3];
89                 /* IMPORTANT, you want to get the error messages from here */
90                 char errorStr[MPD_BUFFER_MAX_LENGTH + 1];
91                 int errorCode;
92                 int errorAt;
93                 /* this will be set to MPD_ERROR_* if there is an error, 0 if not */
94                 int error;
95                 /* DON'T TOUCH any of the rest of this stuff */
96                 int sock;
97                 char buffer[MPD_BUFFER_MAX_LENGTH + 1];
98                 int buflen;
99                 int bufstart;
100                 int doneProcessing;
101                 int listOks;
102                 int doneListOk;
103                 int commandList;
104                 mpd_ReturnElement *returnElement;
105                 struct timeval timeout;
106         } mpd_Connection;
107
108 /* mpd_newConnection
109  * use this to open a new connection
110  * you should use mpd_closeConnection, when your done with the connection,
111  * even if an error has occurred
112  * _timeout_ is the connection timeout period in seconds
113  */
114         mpd_Connection *mpd_newConnection(const char *host, int port,
115                                           float timeout);
116
117         void mpd_setConnectionTimeout(mpd_Connection * connection,
118                                       float timeout);
119
120 /* mpd_closeConnection
121  * use this to close a connection and free'ing subsequent memory
122  */
123         void mpd_closeConnection(mpd_Connection * connection);
124
125 /* mpd_clearError
126  * clears error
127  */
128         void mpd_clearError(mpd_Connection * connection);
129
130 /* STATUS STUFF */
131
132 /* use these with status.state to determine what state the player is in */
133 #define MPD_STATUS_STATE_UNKNOWN        0
134 #define MPD_STATUS_STATE_STOP           1
135 #define MPD_STATUS_STATE_PLAY           2
136 #define MPD_STATUS_STATE_PAUSE          3
137
138 /* us this with status.volume to determine if mpd has volume support */
139 #define MPD_STATUS_NO_VOLUME            -1
140
141 /* mpd_Status
142  * holds info return from status command
143  */
144         typedef struct mpd_Status {
145                 /* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */
146                 int volume;
147                 /* 1 if repeat is on, 0 otherwise */
148                 int repeat;
149                 /* 1 if random is on, 0 otherwise */
150                 int random;
151                 /* playlist length */
152                 int playlistLength;
153                 /* playlist, use this to determine when the playlist has changed */
154                 long long playlist;
155                 /* use with MPD_STATUS_STATE_* to determine state of player */
156                 int state;
157                 /* crossfade setting in seconds */
158                 int crossfade;
159                 /* if a song is currently selected (always the case when state is
160                  * PLAY or PAUSE), this is the position of the currently
161                  * playing song in the playlist, beginning with 0
162                  */
163                 int song;
164                 /* Song ID of the currently selected song */
165                 int songid;
166                 /* time in seconds that have elapsed in the currently playing/paused
167                  * song
168                  */
169                 int elapsedTime;
170                 /* length in seconds of the currently playing/paused song */
171                 int totalTime;
172                 /* current bit rate in kbs */
173                 int bitRate;
174                 /* audio sample rate */
175                 unsigned int sampleRate;
176                 /* audio bits */
177                 int bits;
178                 /* audio channels */
179                 int channels;
180                 /* 1 if mpd is updating, 0 otherwise */
181                 int updatingDb;
182                 /* error */
183                 char *error;
184         } mpd_Status;
185
186         void mpd_sendStatusCommand(mpd_Connection * connection);
187
188 /* mpd_getStatus
189  * returns status info, be sure to free it with mpd_freeStatus()
190  * call this after mpd_sendStatusCommand()
191  */
192         mpd_Status *mpd_getStatus(mpd_Connection * connection);
193
194 /* mpd_freeStatus
195  * free's status info malloc'd and returned by mpd_getStatus
196  */
197         void mpd_freeStatus(mpd_Status * status);
198
199         typedef struct _mpd_Stats {
200                 int numberOfArtists;
201                 int numberOfAlbums;
202                 int numberOfSongs;
203                 unsigned long uptime;
204                 unsigned long dbUpdateTime;
205                 unsigned long playTime;
206                 unsigned long dbPlayTime;
207         } mpd_Stats;
208
209         void mpd_sendStatsCommand(mpd_Connection * connection);
210
211         mpd_Stats *mpd_getStats(mpd_Connection * connection);
212
213         void mpd_freeStats(mpd_Stats * stats);
214
215 /* SONG STUFF */
216
217 #define MPD_SONG_NO_TIME        -1
218 #define MPD_SONG_NO_NUM         -1
219 #define MPD_SONG_NO_ID          -1
220
221 /* mpd_Song
222  * for storing song info returned by mpd
223  */
224         typedef struct _mpd_Song {
225                 /* filename of song */
226                 char *file;
227                 /* artist, maybe NULL if there is no tag */
228                 char *artist;
229                 /* title, maybe NULL if there is no tag */
230                 char *title;
231                 /* album, maybe NULL if there is no tag */
232                 char *album;
233                 /* track, maybe NULL if there is no tag */
234                 char *track;
235                 /* name, maybe NULL if there is no tag; it's the name of the current
236                  * song, f.e. the icyName of the stream */
237                 char *name;
238                 /* length of song in seconds, check that it is not MPD_SONG_NO_TIME  */
239                 int time;
240                 /* if plchanges/playlistinfo/playlistid used, is the position of the 
241                  * song in the playlist */
242                 int pos;
243                 /* song id for a song in the playlist */
244                 int id;
245         } mpd_Song;
246
247 /* mpd_newSong
248  * use to allocate memory for a new mpd_Song
249  * file, artist, etc all initialized to NULL
250  * if your going to assign values to file, artist, etc
251  * be sure to malloc or strdup the memory
252  * use mpd_freeSong to free the memory for the mpd_Song, it will also
253  * free memory for file, artist, etc, so don't do it yourself
254  */
255         mpd_Song *mpd_newSong();
256
257 /* mpd_freeSong
258  * use to free memory allocated by mpd_newSong
259  * also it will free memory pointed to by file, artist, etc, so be careful
260  */
261         void mpd_freeSong(mpd_Song * song);
262
263 /* mpd_songDup
264  * works like strDup, but for a mpd_Song
265  */
266         mpd_Song *mpd_songDup(mpd_Song * song);
267
268 /* DIRECTORY STUFF */
269
270 /* mpd_Directory
271  * used to store info fro directory (right now that just the path)
272  */
273         typedef struct _mpd_Directory {
274                 char *path;
275         } mpd_Directory;
276
277 /* mpd_newDirectory
278  * allocates memory for a new directory
279  * use mpd_freeDirectory to free this memory
280  */
281         mpd_Directory *mpd_newDirectory();
282
283 /* mpd_freeDirectory
284  * used to free memory allocated with mpd_newDirectory, and it frees
285  * path of mpd_Directory, so be careful
286  */
287         void mpd_freeDirectory(mpd_Directory * directory);
288
289 /* mpd_directoryDup
290  * works like strdup, but for mpd_Directory
291  */
292         mpd_Directory *mpd_directoryDup(mpd_Directory * directory);
293
294 /* PLAYLISTFILE STUFF */
295
296 /* mpd_PlaylistFile
297  * stores info about playlist file returned by lsinfo
298  */
299         typedef struct _mpd_PlaylistFile {
300                 char *path;
301         } mpd_PlaylistFile;
302
303 /* mpd_newPlaylistFile
304  * allocates memory for new mpd_PlaylistFile, path is set to NULL
305  * free this memory with mpd_freePlaylistFile
306  */
307         mpd_PlaylistFile *mpd_newPlaylistFile();
308
309 /* mpd_freePlaylist
310  * free memory allocated for freePlaylistFile, will also free
311  * path, so be careful
312  */
313         void mpd_freePlaylistFile(mpd_PlaylistFile * playlist);
314
315 /* mpd_playlistFileDup
316  * works like strdup, but for mpd_PlaylistFile
317  */
318         mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile * playlist);
319
320 /* INFO ENTITY STUFF */
321
322 /* the type of entity returned from one of the commands that generates info
323  * use in conjunction with mpd_InfoEntity.type
324  */
325 #define MPD_INFO_ENTITY_TYPE_DIRECTORY          0
326 #define MPD_INFO_ENTITY_TYPE_SONG               1
327 #define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE       2
328
329 /* mpd_InfoEntity
330  * stores info on stuff returned info commands
331  */
332         typedef struct mpd_InfoEntity {
333                 /* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine
334                  * what this entity is (song, directory, etc...)
335                  */
336                 int type;
337                 /* the actual data you want, mpd_Song, mpd_Directory, etc */
338                 union {
339                         mpd_Directory *directory;
340                         mpd_Song *song;
341                         mpd_PlaylistFile *playlistFile;
342                 } info;
343         } mpd_InfoEntity;
344
345         mpd_InfoEntity *mpd_newInfoEntity();
346
347         void mpd_freeInfoEntity(mpd_InfoEntity * entity);
348
349 /* INFO COMMANDS AND STUFF */
350
351 /* use this function to loop over after calling Info/Listall functions */
352         mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection * connection);
353
354 /* fetches the currently seeletect song (the song referenced by status->song
355  * and status->songid*/
356         void mpd_sendCurrentSongCommand(mpd_Connection * connection);
357
358 /* songNum of -1, means to display the whole list */
359         void mpd_sendPlaylistInfoCommand(mpd_Connection * connection,
360                                          int songNum);
361
362 /* use this to get the changes in the playlist since version _playlist_ */
363         void mpd_sendPlChangesCommand(mpd_Connection * connection,
364                                       long long playlist);
365
366 /* recursivel fetches all songs/dir/playlists in "dir* (no metadata is 
367  * returned) */
368         void mpd_sendListallCommand(mpd_Connection * connection,
369                                     const char *dir);
370
371 /* same as sendListallCommand, but also metadata is returned */
372         void mpd_sendListallInfoCommand(mpd_Connection * connection,
373                                         const char *dir);
374
375 /* non-recursive version of ListallInfo */
376         void mpd_sendLsInfoCommand(mpd_Connection * connection,
377                                    const char *dir);
378
379 #define MPD_TABLE_ARTIST        0
380 #define MPD_TABLE_ALBUM         1
381 #define MPD_TABLE_TITLE         2
382 #define MPD_TABLE_FILENAME      3
383
384         void mpd_sendSearchCommand(mpd_Connection * connection, int table,
385                                    const char *str);
386
387         void mpd_sendFindCommand(mpd_Connection * connection, int table,
388                                  const char *str);
389
390 /* LIST TAG COMMANDS */
391
392 /* use this function fetch next artist entry, be sure to free the returned 
393  * string.  NULL means there are no more.  Best used with sendListArtists
394  */
395         char *mpd_getNextArtist(mpd_Connection * connection);
396
397         char *mpd_getNextAlbum(mpd_Connection * connection);
398
399 /* list artist or albums by artist, arg1 should be set to the artist if
400  * listing albums by a artist, otherwise NULL for listing all artists or albums
401  */
402         void mpd_sendListCommand(mpd_Connection * connection, int table,
403                                  const char *arg1);
404
405 /* SIMPLE COMMANDS */
406
407         void mpd_sendAddCommand(mpd_Connection * connection,
408                                 const char *file);
409
410         void mpd_sendDeleteCommand(mpd_Connection * connection,
411                                    int songNum);
412
413         void mpd_sendDeleteIdCommand(mpd_Connection * connection,
414                                      int songNum);
415
416         void mpd_sendSaveCommand(mpd_Connection * connection,
417                                  const char *name);
418
419         void mpd_sendLoadCommand(mpd_Connection * connection,
420                                  const char *name);
421
422         void mpd_sendRmCommand(mpd_Connection * connection,
423                                const char *name);
424
425         void mpd_sendShuffleCommand(mpd_Connection * connection);
426
427         void mpd_sendClearCommand(mpd_Connection * connection);
428
429 /* use this to start playing at the beginning, useful when in random mode */
430 #define MPD_PLAY_AT_BEGINNING   -1
431
432         void mpd_sendPlayCommand(mpd_Connection * connection, int songNum);
433
434         void mpd_sendPlayIdCommand(mpd_Connection * connection,
435                                    int songNum);
436
437         void mpd_sendStopCommand(mpd_Connection * connection);
438
439         void mpd_sendPauseCommand(mpd_Connection * connection,
440                                   int pauseMode);
441
442         void mpd_sendNextCommand(mpd_Connection * connection);
443
444         void mpd_sendPrevCommand(mpd_Connection * connection);
445
446         void mpd_sendMoveCommand(mpd_Connection * connection, int from,
447                                  int to);
448
449         void mpd_sendMoveIdCommand(mpd_Connection * connection, int from,
450                                    int to);
451
452         void mpd_sendSwapCommand(mpd_Connection * connection, int song1,
453                                  int song2);
454
455         void mpd_sendSwapIdCommand(mpd_Connection * connection, int song1,
456                                    int song2);
457
458         void mpd_sendSeekCommand(mpd_Connection * connection, int song,
459                                  int time);
460
461         void mpd_sendSeekIdCommand(mpd_Connection * connection, int song,
462                                    int time);
463
464         void mpd_sendRepeatCommand(mpd_Connection * connection,
465                                    int repeatMode);
466
467         void mpd_sendRandomCommand(mpd_Connection * connection,
468                                    int randomMode);
469
470         void mpd_sendSetvolCommand(mpd_Connection * connection,
471                                    int volumeChange);
472
473 /* WARNING: don't use volume command, its depreacted */
474         void mpd_sendVolumeCommand(mpd_Connection * connection,
475                                    int volumeChange);
476
477         void mpd_sendCrossfadeCommand(mpd_Connection * connection,
478                                       int seconds);
479
480         void mpd_sendUpdateCommand(mpd_Connection * connection,
481                                    char *path);
482
483 /* returns the update job id, call this after a update command*/
484         int mpd_getUpdateId(mpd_Connection * connection);
485
486         void mpd_sendPasswordCommand(mpd_Connection * connection,
487                                      const char *pass);
488
489 /* after executing a command, when your done with it to get its status
490  * (you want to check connection->error for an error)
491  */
492         void mpd_finishCommand(mpd_Connection * connection);
493
494 /* command list stuff, use this to do things like add files very quickly */
495         void mpd_sendCommandListBegin(mpd_Connection * connection);
496
497         void mpd_sendCommandListOkBegin(mpd_Connection * connection);
498
499         void mpd_sendCommandListEnd(mpd_Connection * connection);
500
501 /* advance to the next listOk 
502  * returns 0 if advanced to the next list_OK,
503  * returns -1 if it advanced to an OK or ACK */
504         int mpd_nextListOkCommand(mpd_Connection * connection);
505
506 /* handles SIGPIPE from full close on the server side */
507         void mpd_signalHandler(int);
508
509 #ifdef __cplusplus
510 }
511 #endif
512 #endif