1 /* libmpd (high level libmpdclient library)
2  * Copyright (C) 2004-2009 Qball Cow <qball@sarine.nl>
3  * Project homepage: http://gmpcwiki.sarine.nl/
4 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14 
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 /**
21  * \example testcase.c
22  * A small example of a console client using libmpd.
23  */
24 
25 /** \defgroup 1Basic Basic
26  */
27 /*@{*/
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 #ifndef __MPD_LIB__
34 #define __MPD_LIB__
35 #ifdef WIN32
36 #define __REGEX_IMPORT__ 1
37 #define __W32API_USE_DLLIMPORT__ 1
38 #endif
39 
40 #include "libmpdclient.h"
41 
42 #ifndef TRUE
43 /** Defined for readability: True is 1. */
44 #define TRUE 1
45 #endif
46 
47 #ifndef FALSE
48 /** Defined for readability: False is 0. */
49 #define FALSE 0
50 #endif
51 #include "libmpd-version.h"
52 extern char *libmpd_version;
53 
54 /**
55  * Enum that represent the errors libmpd functions can return
56  */
57 
58 typedef enum {
59 	/** Command/function completed succesfull */
60 	MPD_OK = 0,
61 	/** Error in the function's arguments */
62 	MPD_ARGS_ERROR = -5,
63 	/** Action failed because there is no connection to an mpd daemon */
64 	MPD_NOT_CONNECTED = -10,
65 	/** Failed to grab status*/
66 	MPD_STATUS_FAILED  = -20,
67 	/** Connection is still locked	 */
68 	MPD_LOCK_FAILED  = -30,
69 	/** Failed to grab status	 */
70 	MPD_STATS_FAILED = -40,
71 	/** Mpd server returned an error	 */
72 	MPD_SERVER_ERROR = -50,
73 	/** Mpd doesn't support this feature */
74 	MPD_SERVER_NOT_SUPPORTED = -51,
75 
76 	/**  The playlist already exists	 */
77 	MPD_DATABASE_PLAYLIST_EXIST  = -60,
78 	/** Playlist is empty */
79 	MPD_PLAYLIST_EMPTY = -70,
80 	/** Playlist queue is empty */
81 	MPD_PLAYLIST_QUEUE_EMPTY = -75,
82 	/** Player isn't Playing */
83 	MPD_PLAYER_NOT_PLAYING = -80,
84 
85 	/** Tag Item not found */
86 	MPD_TAG_NOT_FOUND = -90,
87 
88     /* MPD_PLALIST_LOAD_FAILED */
89     MPD_PLAYLIST_LOAD_FAILED = -100,
90 
91 	/** Fatal error, something I am not sure what todo with */
92 	MPD_FATAL_ERROR = -1000
93 }MpdError;
94 
95 
96 
97 /**
98  *  The Main Mpd Object. Don't access any of the internal values directly, but use the provided functions.
99  */
100 typedef struct _MpdObj MpdObj;
101 
102 /**
103  *
104  * enum that represents the state of a command.
105  */
106 typedef enum {
107 	MPD_SERVER_COMMAND_ALLOWED = TRUE,
108 	MPD_SERVER_COMMAND_NOT_ALLOWED = FALSE,
109 	MPD_SERVER_COMMAND_NOT_SUPPORTED = -1,
110 	MPD_SERVER_COMMAND_ERROR = -2
111 } MpdServerCommand;
112 
113 
114 /**
115  * \ingroup MpdData
116  * enumeration to determine what value the MpdData structure hold.
117  * The MpdData structure can hold only one type of value,
118  * but a list of MpdData structs can hold structs with different type of values.
119  * It's required to check every MpdData Structure.
120  */
121 typedef enum {
122 	/** The MpdData structure holds no value*/
123 	MPD_DATA_TYPE_NONE,
124 	/** Holds an Tag String. value->tag is filled value->tag_type defines what type of tag.*/
125 	MPD_DATA_TYPE_TAG,
126 	/** Holds an Directory String. value->directory is filled.*/
127 	MPD_DATA_TYPE_DIRECTORY,
128 	/** Holds an MpdSong Structure. value->song is valid.*/
129 	MPD_DATA_TYPE_SONG,
130 	/** Holds an Playlist String. value->playlist is filled.*/
131 	MPD_DATA_TYPE_PLAYLIST,
132 	/** Holds an MpdOutputDevice structure. value->output_dev is valid.*/
133 	MPD_DATA_TYPE_OUTPUT_DEV
134 } MpdDataType;
135 
136 /**
137  * \ingroup #MpdData
138  * A fast linked list that is used to pass data from libmpd to the client.
139  */
140 typedef struct _MpdData {
141 	/** a #MpdDataType */
142 	MpdDataType type;
143 	union {
144 		struct {
145 			/** a #mpd_TagItems defining what #tag contains */
146 			int tag_type;
147 			/** a string containing the tag*/
148 			char *tag;
149 		};
150 		/** a directory */
151 		char *directory;
152 		/** a path to a playlist */
153 		mpd_PlaylistFile *playlist;
154 		/** a  mpd_Song */
155 		mpd_Song *song;
156 		/** an output device entity */
157 		mpd_OutputEntity *output_dev;
158 	};
159 
160     void *userdata;
161     void (*freefunc)(void *userdata);
162 } MpdData;
163 
164 
165 #include "libmpd-player.h"
166 #include "libmpd-status.h"
167 #include "libmpd-database.h"
168 #include "libmpd-playlist.h"
169 #include "libmpd-strfsong.h"
170 #include "libmpd-sticker.h"
171 
172 
173 
174 /**
175  * mpd_new_default
176  *
177  * Create a new #MpdObj with default settings.
178  * Hostname will be set to "localhost".
179  * Port will be 6600.
180  *
181  * same as calling:
182  * @code
183  * mpd_new("localhost",6600,NULL);
184  * @endcode
185  *
186  * @returns the new #MpdObj
187  */
188 MpdObj *mpd_new_default();
189 
190 
191 
192 /**
193  * @param hostname The hostname to connect to
194  * @param port The port to connect to
195  * @param password The password to use for the connection, or NULL for no password
196  *
197  * Create a new #MpdObj with provided settings:
198  *
199  * @returns the new #MpdObj
200  */
201 
202 MpdObj *mpd_new(char *hostname, int port, char *password);
203 
204 
205 
206 /**
207  *@param mi a #MpdObj
208  *@param hostname The new hostname to use
209  *
210  * set the hostname
211  *
212  * @returns a #MpdError. (#MPD_OK if everything went ok)
213  */
214 int mpd_set_hostname(MpdObj * mi, char *hostname);
215 
216 /**
217  * @param mi a #MpdObj
218  *
219  * gets the set hostname
220  *
221  * @returns a const char representing the hostname
222  */
223 const char * mpd_get_hostname(MpdObj *mi);
224 
225 /**
226  * @param mi a #MpdObj
227  * @param password The new password to use
228  *
229  * Set the password
230  *
231  * @returns a #MpdError. (#MPD_OK if everything went ok)
232  */
233 int mpd_set_password(MpdObj * mi,const char *password);
234 
235 
236 /**
237  * @param mi a #MpdObj
238  * @param port The port to use. (Default: 6600)
239  *
240  * Set the Port number
241  *
242  *
243  * @returns a #MpdError. (#MPD_OK if everything went ok)
244  */
245 int mpd_set_port(MpdObj * mi, int port);
246 
247 
248 
249 
250 /**
251  * @param mi a #MpdObj
252  * @param timeout: A timeout (in seconds)
253  *
254  * Set the timeout of the connection.
255  * If already connected the timeout of the running connection
256  *
257  * @returns a #MpdError. (MPD_OK if everything went ok)
258  */
259 int mpd_set_connection_timeout(MpdObj * mi, float timeout);
260 
261 
262 int mpd_connect_real(MpdObj *mi,mpd_Connection *connection);
263 /**
264  * @param mi a #MpdObj
265  *
266  * Connect to the mpd daemon.
267  * Warning: mpd_connect connects anonymous, to authenticate use #mpd_send_password
268  *
269  * @returns returns a #MpdError, MPD_OK when successful
270  */
271 int mpd_connect(MpdObj * mi);
272 
273 
274 /**
275  * @param mi The #MpdObj to disconnect
276  *
277  * Disconnect the current connection
278  * @returns MPD_OK (always)
279  */
280 int mpd_disconnect(MpdObj * mi);
281 
282 
283 
284 /**
285  * @param mi	a #MpdObj
286  *
287  * Checks if #MpdObj is connected
288  * @returns True when connected
289  */
290 int mpd_check_connected(MpdObj * mi);
291 
292 
293 
294 /**
295  * @param mi a #MpdObj
296  *
297  * Checks if there was an error
298  * @returns True when there is an error
299  */
300 int mpd_check_error(MpdObj * mi);
301 
302 
303 
304 /**
305  * @param mi a #MpdObj
306  *
307  * Free the #MpdObj, when still connected the connection will be disconnected first
308  */
309 void mpd_free(MpdObj * mi);
310 
311 
312 
313 /**
314  * @param mi a #MpdObj
315  *
316  * Forces libmpd to re-authenticate itself.
317  *
318  * When successful it will trigger the "permission" changed signal.
319  *
320  * @returns: a #MpdError
321  */
322 int mpd_send_password(MpdObj * mi);
323 
324 
325 
326 /*
327  * signals
328  */
329 
330 /**
331  * Bitwise enumeration to determine what triggered the status_changed signals
332  * This is used in combination with the #StatusChangedCallback
333  * @code
334  * void status_changed_callback(MpdObj *mi, ChangedStatusType what)
335  * {
336  *	if(what&MPD_CST_SONGID)
337  *	{
338  *		// act on song change
339  *
340  *	}
341  *	if(what&MPD_CST_RANDOM)
342  *	{
343  *		// act on random change
344  *	}
345  *	// etc.
346  * }
347  * @endcode
348  */
349 typedef enum {
350 	/** The playlist has changed */
351 	MPD_CST_PLAYLIST      = 0x0001,
352 	/** The song position of the playing song has changed*/
353 	MPD_CST_SONGPOS       = 0x0002,
354 	/** The songid of the playing song has changed */
355 	MPD_CST_SONGID        = 0x0004,
356 	/** The database has changed. */
357 	MPD_CST_DATABASE      = 0x0008,
358 	/** the state of updating the database has changed.*/
359 	MPD_CST_UPDATING      = 0x0010,
360 	/** the volume has changed */
361 	MPD_CST_VOLUME        = 0x0020,
362 	/** The total time of the currently playing song has changed*/
363 	MPD_CST_TOTAL_TIME    = 0x0040,
364  	/** The elapsed time of the current song has changed.*/
365 	MPD_CST_ELAPSED_TIME  = 0x0080,
366 	/** The crossfade time has changed. */
367 	MPD_CST_CROSSFADE     = 0x0100,
368 	/** The random state is changed.     */
369 	MPD_CST_RANDOM        = 0x0200,
370 	/** repeat state is changed.     */
371 	MPD_CST_REPEAT        = 0x0400,
372 	/** Not implemented  */
373 	MPD_CST_AUDIO         = 0x0800,
374 	/** The state of the player has changed.*/
375 	MPD_CST_STATE         = 0x1000,
376 	/** The permissions the client has, has changed.*/
377 	MPD_CST_PERMISSION    = 0x2000,
378 	/** The bitrate of the playing song has changed.    */
379 	MPD_CST_BITRATE       = 0x4000,
380 	/** the audio format of the playing song changed.*/
381 	MPD_CST_AUDIOFORMAT   = 0x8000,
382 	/** the queue has changed */
383 	MPD_CST_STORED_PLAYLIST		  = 0x20000,
384     /** server error */
385     MPD_CST_SERVER_ERROR        = 0x40000,
386     /** output changed */
387     MPD_CST_OUTPUT              = 0x80000,
388     /** Sticker changed */
389     MPD_CST_STICKER             = 0x100000,
390     /** Next song changed */
391     MPD_CST_NEXTSONG            = 0x200000,
392     /** Single mode changed */
393     MPD_CST_SINGLE_MODE         = 0x400000,
394     /** Consume mode changed */
395     MPD_CST_CONSUME_MODE        = 0x800000,
396     /** Replaygain mode changed */
397     MPD_CST_REPLAYGAIN          = 0x1000000
398 } ChangedStatusType;
399 
400 
401 /* callback typedef's */
402 /**
403  * @param mi a #MpdObj
404  * @param what a #ChangedStatusType that determines what changed triggered the signal. This is a bitmask.
405  * @param userdata user data set when the signal handler was connected.
406  *
407  * Signal that gets called when the state of mpd has changed. Look #ChangedStatusType to see the possible events.
408  */
409 typedef void (*StatusChangedCallback) (MpdObj * mi, ChangedStatusType what, void *userdata);
410 
411 
412 
413 
414 /**
415  * @param mi a #MpdObj
416  * @param id The error Code.
417  * @param msg human-readable informative error message.
418  * @param userdata  user data set when the signal handler was connected.
419  * This signal is called when an error has occurred in the communication with mpd.
420  *
421  * return: TRUE if libmpd should disconnect.
422  */
423 typedef int (*ErrorCallback) (MpdObj * mi, int id, char *msg, void *userdata);
424 
425 
426 
427 /**
428  * @param mi a #MpdObj
429  * @param connect 1 if you are now connected, 0 if you are disconnected.
430  * @param userdata  user data set when the signal handler was connected.
431  * Signal is triggered when the connection state changes.
432  */
433 
434 typedef void (*ConnectionChangedCallback) (MpdObj * mi, int connect, void *userdata);
435 
436 
437 
438 /* new style signal connectors */
439 /**
440  * @param mi a #MpdObj
441  * @param status_changed a #StatusChangedCallback
442  * @param userdata user data passed to the callback
443  */
444 void mpd_signal_connect_status_changed(MpdObj * mi, StatusChangedCallback status_changed,
445 					       void *userdata);
446 
447 
448 
449 /**
450  * @param mi a #MpdObj
451  * @param error a #ErrorCallback
452  * @param userdata user data passed to the callback
453  */
454 void mpd_signal_connect_error(MpdObj * mi, ErrorCallback error, void *userdata);
455 
456 
457 
458 /**
459  * @param mi a #MpdObj
460  * @param connection_changed a #ConnectionChangedCallback
461  * @param userdata user data passed to the callback
462  */
463 void mpd_signal_connect_connection_changed(MpdObj * mi,
464 						   ConnectionChangedCallback connection_changed,
465 						   void *userdata);
466 
467 /*@}*/
468 
469 
470 
471 /**\defgroup MpdData Data Object
472  * This is a fast linked list implementation where data returned from mpd is stored in.
473  */
474 
475 /*@{*/
476 
477 /**
478  * @param data a #MpdData
479  *
480  * Checks if the passed #MpdData is the last in a list
481  * @returns TRUE when data is the last in the list.
482  */
483 int mpd_data_is_last(MpdData const *data);
484 
485 
486 /**
487  * @param data a #MpdData
488  *
489  * Free's a #MpdData List
490  */
491 void mpd_data_free(MpdData * data);
492 
493 
494 
495 /**
496  * @param data a #MpdData
497  *
498  * Returns the next #MpdData in the list.
499  * If it's the last item in the list, it will free the list.
500  *
501  * You can iterate through a list like this and have it freed afterwards.
502  * @code
503  *	for(data = mpd_database_get_albums(mi);data != NULL; data = mpd_data_get_next(data))
504  *	{
505  *		// do your thing
506  *	}
507  * @endcode
508  * @returns The next #MpdData or %NULL
509  */
510 MpdData *mpd_data_get_next(MpdData * data);
511 
512 
513 
514 
515 /**
516  * @param data a #MpdData
517  *
518  * Returns the first #MpdData in the list.
519  *
520  * @returns The first #MpdData or %NULL
521  */
522 MpdData *mpd_data_get_first(MpdData const *data);
523 
524 
525 
526 /**
527  * @param data a #MpdData item
528  *
529  * removes the passed #MpdData from the underlying list, and returns the element before data
530  *
531  * @returns a #MpdData list
532  */
533 MpdData *mpd_data_delete_item(MpdData * data);
534 
535 
536 
537 /*@}*/
538 
539 
540 /** \defgroup Server Server
541  * Functions to get information about the mpd daemon and or modify it.
542  */
543 /*@{*/
544 
545 
546 /**
547  * @param mi a #MpdObj
548  *
549  * Returns a list of audio output devices stored in a #MpdData list
550  *
551  * @returns a #MpdData
552  */
553 MpdData *mpd_server_get_output_devices(MpdObj * mi);
554 
555 
556 
557 /**
558  * @param mi a #MpdObj
559  * @param device_id The id of the output device
560  * @param state The state to change the output device to, 1 is enable, 0 is disable.
561  *
562  * Enable or Disable an audio output device
563  *
564  * @returns 0 if successful
565  */
566 int mpd_server_set_output_device(MpdObj * mi, int device_id, int state);
567 
568 
569 
570 /**
571  * @param mi a #MpdObj
572  *
573  * Gets a unix timestamp of the last time the database was updated.
574  *
575  * @returns unix Timestamp
576  */
577 long unsigned mpd_server_get_database_update_time(MpdObj * mi);
578 
579 
580 
581 /**
582  * @param mi a #MpdObj
583  * @param major the major version number
584  * @param minor the minor version number
585  * @param micro the micro version number
586  *
587  * Checks if the connected mpd server version is equal or higher.
588  *
589  * @returns #TRUE when version of mpd equals or is higher, else #FALSE
590  */
591 int mpd_server_check_version(MpdObj * mi, int major, int minor, int micro);
592 
593 /**
594  * @param mi a #MpdObj
595  *
596  * @return a string with version or NULL when not connected
597  */
598 
599 char *mpd_server_get_version(MpdObj *mi);
600 /**
601  * @param mi a #MpdObj
602  * @param command the command to check
603  *
604  * Checks if the user is allowed to execute the command and if the server supports it
605  *
606  * @returns Returns #MpdServerCommand
607  */
608 int mpd_server_check_command_allowed(MpdObj * mi, const char *command);
609 
610 
611 
612 /**
613  * @param mi a #MpdObj
614  *
615  * @returns an array with urlhandlers (NULL terminated). Result must be freed.
616  */
617 char ** mpd_server_get_url_handlers(MpdObj *mi);
618 
619 /**
620  * @param mi a #MpdObj
621  *
622  * @returns an array with supported tag types. (NULL Terminated). Result must be freed.
623  */
624 
625 char ** mpd_server_get_tag_types(MpdObj *mi);
626 /*@}*/
627 
628 /** \defgroup Misc Misc
629  * Helper functions.
630  */
631 /*@{*/
632 
633 /**
634  * @param name a NULL terminated string
635  *
636  * gets the Matching #MpdDataType matching at the string
637  *
638  * @returns a #MpdDataType
639  */
640 int mpd_misc_get_tag_by_name(char *name);
641 
642 /*@}*/
643 
644 /**
645  * @param mi a #MpdObj
646  *
647  * Reports if the connected mpd supports the idle command.
648  *
649  * @returns a boolean, TRUE if it has idle support
650  */
651 int mpd_server_has_idle(MpdObj *mi);
652 
653 /**
654  * @param mi a #MpdObj
655  * @param tag a #mpd_TagItems
656  *
657  * Returns if mpd supports this tag.
658  *
659  * return 1 if support 0 if not
660  */
661 int mpd_server_tag_supported(MpdObj *mi, int tag);
662 
663 
664 typedef enum {
665     MPD_SERVER_REPLAYGAIN_MODE_OFF = 0,
666     MPD_SERVER_REPLAYGAIN_MODE_TRACK = 1,
667     MPD_SERVER_REPLAYGAIN_MODE_ALBUM = 2,
668     MPD_SERVER_REPLAYGAIN_MODE_AUTO = 3
669 }MpdServerReplaygainMode;
670 
671 MpdServerReplaygainMode mpd_server_get_replaygain_mode(MpdObj *mi);
672 
673 int mpd_server_set_replaygain_mode(MpdObj *mi, MpdServerReplaygainMode mode);
674 
675 #endif
676 
677 #ifdef __cplusplus
678 }
679 #endif
680