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