void cmd_playlists_list (xmmsc_connection_t *conn, gint argc, gchar **argv) { const gchar *active_name; xmmsc_result_t *res, *active_res; xmmsv_t *val, *active_val; xmmsv_list_iter_t *it; active_res = xmmsc_playlist_current_active (conn); xmmsc_result_wait (active_res); active_val = xmmsc_result_get_value (active_res); if (xmmsv_is_error (active_val) || !xmmsv_get_string (active_val, &active_name)) { active_name = NULL; } res = xmmsc_playlist_list (conn); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_is_error (val)) { print_error ("%s", xmmsv_get_error_old (val)); } xmmsv_get_list_iter (val, &it); while (xmmsv_list_iter_valid (it)) { xmmsv_t *valstr; const gchar *name; xmmsv_list_iter_entry (it, &valstr); if (!xmmsv_get_string (valstr, &name)) { print_error ("Broken resultset"); } /* Hide all lists that start with _ */ if (name[0] != '_') { if (active_name != NULL && strcmp (active_name, name) == 0) { print_info ("->%s", name); } else { print_info (" %s", name); } } xmmsv_list_iter_next (it); } xmmsc_result_unref (res); xmmsc_result_unref (active_res); }
static gboolean ol_player_xmms2_go_rel (int rel) { ol_log_func (); ol_debugf (" rel:%d\n", rel); if (!ol_player_xmms2_ensure_connection ()) return FALSE; xmmsc_result_t *result = xmmsc_playlist_set_next_rel (connection, rel); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ol_debug ("Error on setting playlist next"); return FALSE; } xmmsc_result_unref (result); result = xmmsc_playback_tickle (connection); xmmsc_result_wait (result); if (xmmsc_result_iserror (result)) { ol_debug ("Error on tickle playback"); return FALSE; } xmmsc_result_unref (result); return TRUE; }
static gint refresh_active_playlist (xmmsv_t *val, void *udata) { cli_cache_t *cache = (cli_cache_t *) udata; xmmsv_list_iter_t *it; gint32 id; if (!xmmsv_is_error (val)) { /* Reset array */ if (cache->active_playlist->len > 0) { gint len = cache->active_playlist->len; cache->active_playlist = g_array_remove_range (cache->active_playlist, 0, len); } xmmsv_get_list_iter (val, &it); /* .. and refill it */ while (xmmsv_list_iter_valid (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); xmmsv_get_int (entry, &id); g_array_append_val (cache->active_playlist, id); xmmsv_list_iter_next (it); } } freshness_received (&cache->freshness_active_playlist); return TRUE; }
static int32_t ol_player_xmms2_get_currend_id () { /* ol_log_func (); */ if (!ol_player_xmms2_ensure_connection ()) return 0; int32_t ret = 0; xmmsc_result_t *result = xmmsc_playback_current_id (connection); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ol_error ("Error on getting current id"); ret = 0; } else { if (!xmmsv_get_int (return_value, &ret)) { ol_error ("Get id from result failed"); ret = 0; } } xmmsc_result_unref (result); return ret; }
static gboolean ol_player_xmms2_get_music_length (int *len) { /* ol_log_func (); */ ol_assert_ret (len != NULL, FALSE); if (!ol_player_xmms2_ensure_connection ()) return FALSE; *len = 0; int32_t id = ol_player_xmms2_get_currend_id (); if (id > 0) { xmmsc_result_t *result = xmmsc_medialib_get_info (connection, id); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ol_error ("Get music info from XMMS2 failed."); } else { xmmsv_t *dict = xmmsv_propdict_to_dict (return_value, NULL); *len = ol_player_xmms2_get_dict_int (return_value, "duration"); xmmsv_unref (dict); } xmmsc_result_unref (result); } return TRUE; }
Dict::Dict( xmmsv_t* val ) : value_( 0 ) { if( xmmsv_is_error( val ) ) { const char *buf; xmmsv_get_error( val, &buf ); throw value_error( buf ); } else if( xmmsv_get_type( val ) != XMMSV_TYPE_DICT ) { throw not_dict_error( "Value is not a dict" ); } setValue( val ); }
static gint refresh_playback_status (xmmsv_t *val, void *udata) { cli_cache_t *cache = (cli_cache_t *) udata; if (!xmmsv_is_error (val)) { xmmsv_get_int (val, &cache->playback_status); } freshness_received (&cache->freshness_playback_status); return TRUE; }
static gint refresh_currid (xmmsv_t *val, void *udata) { cli_cache_t *cache = (cli_cache_t *) udata; if (!xmmsv_is_error (val)) { xmmsv_get_int (val, &cache->currid); } freshness_received (&cache->freshness_currid); return TRUE; }
static gint refresh_active_playlist (xmmsv_t *val, void *udata) { cli_cache_t *cache = (cli_cache_t *) udata; if (!xmmsv_is_error (val)) { xmmsv_unref (cache->active_playlist); cache->active_playlist = xmmsv_ref (val); } freshness_received (&cache->freshness_active_playlist); return TRUE; }
static gint refresh_active_playlist_name (xmmsv_t *val, void *udata) { cli_cache_t *cache = (cli_cache_t *) udata; const gchar *buf; if (!xmmsv_is_error (val) && xmmsv_get_string (val, &buf)) { g_free (cache->active_playlist_name); cache->active_playlist_name = g_strdup (buf); } freshness_received (&cache->freshness_active_playlist_name); return TRUE; }
static gint refresh_currpos (xmmsv_t *val, void *udata) { cli_cache_t *cache = (cli_cache_t *) udata; if (!xmmsv_is_error (val)) { xmmsv_dict_entry_get_int (val, "position", &cache->currpos); } else { /* Current pos not set */ cache->currpos = -1; } freshness_received (&cache->freshness_currpos); return TRUE; }
void cmd_addpls (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *playlist; xmmsc_result_t *res, *res2; xmmsv_t *val; xmmsv_coll_t *coll; gchar *url; if (argc < 3) { print_error ("Supply path to playlist file"); } if (argc == 3) { playlist = NULL; url = format_url (argv[2], G_FILE_TEST_IS_REGULAR); } else { playlist = argv[2]; url = format_url (argv[3], G_FILE_TEST_IS_REGULAR); } res = xmmsc_coll_idlist_from_playlist_file (conn, url); g_free (url); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_is_error (val)) { print_error ("%s", xmmsv_get_error_old (val)); } if (!xmmsv_get_coll (val, &coll)) { print_error ("Couldn't get collection from result!"); } res2 = xmmsc_playlist_add_idlist (conn, playlist, coll); xmmsc_result_wait (res2); if (xmmsc_result_iserror (res2)) { print_error ("%s", xmmsc_result_get_error (res2)); } print_info ("Playlist with %d entries added", xmmsv_coll_idlist_get_size (coll)); xmmsc_result_unref (res); xmmsc_result_unref (res2); }
void cmd_playlist_active (xmmsc_connection_t *conn, gint argc, gchar **argv) { const gchar *active_name; xmmsc_result_t *active_res; xmmsv_t *active_val; active_res = xmmsc_playlist_current_active (conn); xmmsc_result_wait (active_res); active_val = xmmsc_result_get_value (active_res); if (!xmmsv_is_error (active_val) && xmmsv_get_string (active_val, &active_name)) { print_info ("%s",active_name); } xmmsc_result_unref (active_res); }
static gboolean ol_player_xmms2_get_music_info (OlMusicInfo *info) { /* ol_log_func (); */ ol_assert_ret (info != NULL, FALSE); if (!ol_player_xmms2_ensure_connection ()) return FALSE; ol_music_info_clear (info); int32_t id = ol_player_xmms2_get_currend_id (); if (id > 0) { xmmsc_result_t *result = xmmsc_medialib_get_info (connection, id); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ol_error ("Get music info from XMMS2 failed."); } else { xmmsv_t *dict = xmmsv_propdict_to_dict (return_value, NULL); info->title = ol_player_xmms2_get_dict_string (dict, "title"); info->artist = ol_player_xmms2_get_dict_string (dict, "artist"); info->album = ol_player_xmms2_get_dict_string (dict, "album"); info->track_number = ol_player_xmms2_get_dict_int (dict, "tracknr"); info->uri = ol_player_xmms2_get_dict_string (dict, "url"); ol_logf (OL_DEBUG, "%s\n" " title:%s\n" " artist:%s\n" " album:%s\n" " uri:%s\n", __FUNCTION__, info->title, info->artist, info->album, info->uri); xmmsv_unref (dict); } xmmsc_result_unref (result); } return TRUE; }
static enum OlPlayerStatus ol_player_xmms2_get_status () { if (!ol_player_xmms2_ensure_connection ()) return OL_PLAYER_ERROR; int ret; xmmsc_result_t *result = xmmsc_playback_status (connection); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ret = OL_PLAYER_ERROR; } else { int32_t status; if (xmmsv_get_int (return_value, &status)) { switch (status) { case XMMS_PLAYBACK_STATUS_STOP: ret = OL_PLAYER_STOPPED; break; case XMMS_PLAYBACK_STATUS_PLAY: ret = OL_PLAYER_PLAYING; break; case XMMS_PLAYBACK_STATUS_PAUSE: ret = OL_PLAYER_PAUSED; break; default: ret = OL_PLAYER_UNKNOWN; break; } } else { ret = OL_PLAYER_ERROR; } } xmmsc_result_unref (result); return ret; }
gboolean playlist_exists (cli_infos_t *infos, gchar *playlist) { gboolean retval = FALSE; xmmsc_result_t *res; xmmsv_t *val; res = xmmsc_coll_get (infos->sync, playlist, XMMS_COLLECTION_NS_PLAYLISTS); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (!xmmsv_is_error (val)) { retval = TRUE; } xmmsc_result_unref (res); return retval; }
int xmmsc_connect (xmmsc_connection_t *c, const char *ipcpath) { xmmsc_ipc_t *ipc; xmmsc_result_t *result; xmmsv_t *value; const char *buf; x_api_error_if (!c, "with a NULL connection", false); if (!ipcpath) { if (!xmms_default_ipcpath_get (c->path, sizeof (c->path))) { return false; } } else { snprintf (c->path, sizeof (c->path), "%s", ipcpath); } ipc = xmmsc_ipc_init (); if (!xmmsc_ipc_connect (ipc, c->path)) { c->error = strdup ("xmms2d is not running."); xmmsc_ipc_destroy (ipc); return false; } c->ipc = ipc; result = xmmsc_send_hello (c); xmmsc_result_wait (result); value = xmmsc_result_get_value (result); if (xmmsv_is_error (value)) { xmmsv_get_error (value, &buf); c->error = strdup (buf); xmmsc_result_unref (result); return false; } xmmsc_result_unref (result); return true; }
static gboolean ol_player_xmms2_get_played_time (int *played_time) { /* ol_log_func (); */ ol_assert_ret (played_time != NULL, FALSE); if (!ol_player_xmms2_ensure_connection ()) return FALSE; xmmsc_result_t *result = xmmsc_playback_playtime (connection); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ol_error ("Get played time from XMMS2 failed"); return FALSE; } int32_t elapsed = 0; xmmsv_get_int (return_value, &elapsed); *played_time = elapsed; xmmsc_result_unref (result); /* ol_debugf ("time: %d\n", *played_time); */ return TRUE; }
void cmd_list (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *playlist = NULL; xmmsc_result_t *res; xmmsv_t *val; xmmsv_list_iter_t *it; gulong total_playtime = 0; gint p = 0; guint pos = 0; if (argc > 2) { playlist = argv[2]; } res = xmmsc_playlist_current_pos (conn, playlist); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (!xmmsv_is_error (val)) { if (!xmmsv_dict_entry_get_int (val, "position", &p)) { print_error ("Broken resultset"); } xmmsc_result_unref (res); } res = xmmsc_playlist_list_entries (conn, playlist); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_is_error (val)) { print_error ("%s", xmmsv_get_error_old (val)); } xmmsv_get_list_iter (val, &it); while (xmmsv_list_iter_valid (it)) { xmmsc_result_t *info_res; xmmsv_t *val_id, *propdict, *info_val; gchar line[80]; gint playtime = 0; guint ui; xmmsv_list_iter_entry (it, &val_id); if (!xmmsv_get_uint (val_id, &ui)) { print_error ("Broken resultset"); } info_res = xmmsc_medialib_get_info (conn, ui); xmmsc_result_wait (info_res); propdict = xmmsc_result_get_value (info_res); info_val = xmmsv_propdict_to_dict (propdict, NULL); if (xmmsv_is_error (info_val)) { print_error ("%s", xmmsv_get_error_old (info_val)); } if (xmmsv_dict_entry_get_int (info_val, "duration", &playtime)) { total_playtime += playtime; } if (val_has_key (info_val, "channel")) { if (val_has_key (info_val, "title")) { xmmsc_entry_format (line, sizeof (line), "[stream] ${title}", info_val); } else { xmmsc_entry_format (line, sizeof (line), "${channel}", info_val); } } else if (!val_has_key (info_val, "title")) { const gchar *url; gchar dur[10]; xmmsc_entry_format (dur, sizeof (dur), "(${minutes}:${seconds})", info_val); if (xmmsv_dict_entry_get_string (info_val, "url", &url)) { gchar *filename = g_path_get_basename (url); if (filename) { g_snprintf (line, sizeof (line), "%s %s", filename, dur); g_free (filename); } else { g_snprintf (line, sizeof (line), "%s %s", url, dur); } } } else { xmmsc_entry_format (line, sizeof (line), listformat, info_val); } if (p == pos) { print_info ("->[%d/%d] %s", pos, ui, line); } else { print_info (" [%d/%d] %s", pos, ui, line); } pos++; xmmsc_result_unref (info_res); xmmsv_unref (info_val); xmmsv_list_iter_next (it); } xmmsc_result_unref (res); /* rounding */ total_playtime += 500; print_info ("\nTotal playtime: %d:%02d:%02d", total_playtime / 3600000, (total_playtime / 60000) % 60, (total_playtime / 1000) % 60); }
int main (int argc, char **argv) { /* * To connect to xmms2d you need to first have a * connection. */ xmmsc_connection_t *connection; /* * xmmsc_result_t is the struct returned from all * commands that are given to the xmms2d server * we just declare a variable of this type here, * we'll need it later. */ xmmsc_result_t *result; /* * xmmsv_t is the wrapper struct used to communicate * values to/from the server. Typically, when a client * issues commands, the server answers by sending back * the return value for the command. Here, we will only * use it to check if the server returned an error. */ xmmsv_t *return_value; /* * We need a string pointer to retrieve the error (if any) * from the xmmsv_t. Note that the string will still be * owned by the xmmsv_t structure. */ const char *err_buf; /* * First we need to initialize the connection; * as argument you need to pass "name" of your * client. The name has to be in the range [a-zA-Z0-9] * because xmms is deriving configuration values * from this name. */ connection = xmmsc_init ("tutorial1"); /* * xmmsc_init will return NULL if memory is * not available */ if (!connection) { fprintf (stderr, "OOM!\n"); exit (EXIT_FAILURE); } /* * Now we need to connect to xmms2d. We need to * pass the XMMS ipc-path to the connect call. * If passed NULL, it will default to * unix:///tmp/xmms-ipc-<user>, but all xmms2 clients * should handle the XMMS_PATH enviroment in * order to configure connection path. * * xmmsc_connect will return NULL if an error occured * and it will set the xmmsc_get_last_error() to a * string describing the error */ if (!xmmsc_connect (connection, getenv ("XMMS_PATH"))) { fprintf (stderr, "Connection failed: %s\n", xmmsc_get_last_error (connection)); exit (EXIT_FAILURE); } /* * This is all you have to do to connect to xmms2d. * Now we can send commands. Let's do something easy * like getting xmms2d to start playback. */ result = xmmsc_playback_start (connection); /* * The command will be sent, and since this is a * synchronous connection we can block for its * return here. The async / sync issue will be * commented on later. */ xmmsc_result_wait (result); /* * When xmmsc_result_wait() returns, we have the * answer from the server. We now extract that value * from the result. Note that the value is still owned * by the result, and will be freed along with it. */ return_value = xmmsc_result_get_value (result); /* * Let's check if the value returned by the server * is an error, and print it out if it is. */ if (xmmsv_is_error (return_value) && xmmsv_get_error (return_value, &err_buf)) { fprintf (stderr, "playback start returned error, %s", err_buf); } /* * This is very important - when we are done with the * result we need to tell that to the clientlib, * we do that by unrefing it. this will free resources, * including the return_value, and make sure that we don't * leak memory. It is not possible to touch the result or * the return_value after we have done this. */ xmmsc_result_unref (result); /* * Now we are done, let's disconnect and free up all * used resources. */ xmmsc_unref (connection); return (EXIT_SUCCESS); }
void cmd_playlist_type (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *name; xmmsv_coll_type_t prevtype, newtype; xmmsc_result_t *res; xmmsv_t *val; xmmsv_coll_t *coll; /* Read playlist name */ if (argc < 4) { print_error ("usage: type_playlist [playlistname] [type] [options]"); } name = argv[3]; /* Retrieve the playlist operator */ res = xmmsc_coll_get (conn, name, XMMS_COLLECTION_NS_PLAYLISTS); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_is_error (val)) { print_error ("%s", xmmsv_get_error_old (val)); } xmmsv_get_coll (val, &coll); prevtype = xmmsv_coll_get_type (coll); /* No type argument, simply display the current type */ if (argc < 5) { print_info (get_playlist_type_string (prevtype)); /* Type argument, set the new type */ } else { gint typelen; gint idlistsize; xmmsc_result_t *saveres; xmmsv_coll_t *newcoll; gint i; typelen = strlen (argv[4]); if (g_ascii_strncasecmp (argv[4], "list", typelen) == 0) { newtype = XMMS_COLLECTION_TYPE_IDLIST; } else if (g_ascii_strncasecmp (argv[4], "queue", typelen) == 0) { newtype = XMMS_COLLECTION_TYPE_QUEUE; } else if (g_ascii_strncasecmp (argv[4], "pshuffle", typelen) == 0) { newtype = XMMS_COLLECTION_TYPE_PARTYSHUFFLE; /* Setup operand for party shuffle (set operand) ! */ if (argc < 6) { print_error ("Give the source collection for the party shuffle"); } } else { print_error ("Invalid playlist type (valid types: list, queue, pshuffle)"); } /* Copy collection idlist, attributes and operand (if needed) */ newcoll = xmmsv_coll_new (newtype); idlistsize = xmmsv_coll_idlist_get_size (coll); for (i = 0; i < idlistsize; i++) { guint id; xmmsv_coll_idlist_get_index (coll, i, &id); xmmsv_coll_idlist_append (newcoll, id); } xmmsv_coll_attribute_foreach (coll, coll_copy_attributes, newcoll); if (newtype == XMMS_COLLECTION_TYPE_PARTYSHUFFLE) { playlist_setup_pshuffle (conn, newcoll, argv[5]); } /* Overwrite with new collection */ saveres = xmmsc_coll_save (conn, newcoll, name, XMMS_COLLECTION_NS_PLAYLISTS); xmmsc_result_wait (saveres); if (xmmsc_result_iserror (saveres)) { print_error ("Couldn't save %s : %s", name, xmmsc_result_get_error (saveres)); } xmmsv_coll_unref (newcoll); xmmsc_result_unref (saveres); } xmmsc_result_unref (res); }
int main (int argc, char **argv) { /* * The first part of this program is * commented on in tut1.c and tut2.c */ xmmsc_connection_t *connection; xmmsc_result_t *result; xmmsv_t *return_value; const char *err_buf; /* * Variables that we'll need later */ const char *val; int intval; int id; xmmsv_t *dict_entry; xmmsv_t *infos; connection = xmmsc_init ("tutorial3"); if (!connection) { fprintf (stderr, "OOM!\n"); exit (EXIT_FAILURE); } if (!xmmsc_connect (connection, getenv ("XMMS_PATH"))) { fprintf (stderr, "Connection failed: %s\n", xmmsc_get_last_error (connection)); exit (EXIT_FAILURE); } /* * Ok, let' do the same thing as we did in * tut2.c and retrieve the current playing * entry. We need that to get information * about the song. */ result = xmmsc_playback_current_id (connection); xmmsc_result_wait (result); return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value) && xmmsv_get_error (return_value, &err_buf)) { fprintf (stderr, "playback current id returns error, %s\n", err_buf); } if (!xmmsv_get_int (return_value, &id)) { fprintf (stderr, "xmmsc_playback_current_id didn't " "return int as expected\n"); /* Fake id (ids are >= 1) used as an error flag. */ id = 0; } /* Print the value */ printf ("Currently playing id is %d\n", id); /* * Same drill as before. Release memory * so that we can reuse it in the next * clientlib call. * */ xmmsc_result_unref (result); /* * Something about the medialib and xmms2. All * entries that are played, put into playlists * have to be in the medialib. A song's metadata * will be added to the medialib the first time * you do "xmms2 add" or equivalent. * * When we request information for an entry, it will * be requested from the medialib, not the playlist * or the playback. The playlist and playback only * know the unique id of the entry. All other * information must be retrieved in subsequent calls. * * Entry 0 is non valid. Only 1-inf is valid. * So let's check for 0 and don't ask medialib for it. */ if (id == 0) { fprintf (stderr, "Nothing is playing.\n"); exit (EXIT_FAILURE); } /* * And now for something about return types from * clientlib. The clientlib will always return * an xmmsc_result_t that will eventually contain the * return value as a xmmsv_t struct. * The value can contain an int and string as * base type. It can also contain more complex * types like lists and dicts. * A list is a sequence of values, each of them * wrapped in its own xmmsv_t struct (of any type). * A dict is a key<->value representation where key * is always a string but the value is again wrapped * in its own xmmsv_t struct (of any type). * * When retrieving an entry from the medialib, you * get a dict as return. Let's print out some * entries from it and then traverse the dict. */ result = xmmsc_medialib_get_info (connection, id); /* And waaait for it .. */ xmmsc_result_wait (result); /* Let's reuse the previous return_value pointer, it * was invalidated as soon as we freed the result that * contained it anyway. */ return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value) && xmmsv_get_error (return_value, &err_buf)) { /* * This can return error if the id * is not in the medialib */ fprintf (stderr, "medialib get info returns error, %s\n", err_buf); exit (EXIT_FAILURE); } /* * Because of the nature of the dict returned by * xmmsc_medialib_get_info, we need to convert it to * a simpler dict using xmmsv_propdict_to_dict. * Let's not worry about that for now and accept it * as a fact of life. * * See tut5 for a discussion about dicts and propdicts. * * Note that xmmsv_propdict_to_dict creates a new * xmmsv_t struct, which we will need to free manually * when we're done with it. */ infos = xmmsv_propdict_to_dict (return_value, NULL); /* * We must first retrieve the xmmsv_t struct * corresponding to the "artist" key in the dict, * and then extract the string from that struct. */ if (!xmmsv_dict_get (infos, "artist", &dict_entry) || !xmmsv_get_string (dict_entry, &val)) { /* * if we end up here it means that the key "artist" wasn't * in the dict or that the value for "artist" wasn't a * string. * * You can check the type of the entry (if there is one) with * xmmsv_get_type (dict_entry). It will return an * xmmsv_type_t enum describing the type. * * Actually this is no disaster, it might just mean that * we don't have an artist tag on this entry. Let's * call it "No Artist" for now. */ val = "No Artist"; } /* print the value */ printf ("artist = %s\n", val); if (!xmmsv_dict_get (infos, "title", &dict_entry) || !xmmsv_get_string (dict_entry, &val)) { val = "No Title"; } printf ("title = %s\n", val); /* * Let's extract an integer as well */ if (!xmmsv_dict_get (infos, "bitrate", &dict_entry) || !xmmsv_get_int (dict_entry, &intval)) { intval = 0; } printf ("bitrate = %i\n", intval); /* * We need to free infos manually here, else we will leak. */ xmmsv_unref (infos); /* * !!Important!! * * When unreffing the result here we will free * the memory that we have extracted from the dict, * and that includes all the string pointers of the * dict entries! So if you want to keep strings * somewhere you need to copy that memory! Very * important otherwise you will get undefined behaviour. */ xmmsc_result_unref (result); xmmsc_unref (connection); return (EXIT_SUCCESS); }