void list_plugins (cli_infos_t *infos, xmmsc_result_t *res) { const gchar *name, *desc, *err; xmmsv_t *val; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *elem; xmmsv_list_iter_entry (it, &elem); xmmsv_dict_entry_get_string (elem, "shortname", &name); xmmsv_dict_entry_get_string (elem, "description", &desc); g_printf ("%s - %s\n", name, desc); } } else { g_printf (_("Server error: %s\n"), err); } xmmsc_result_unref (res); cli_infos_loop_resume (infos); }
static void print_collections_list (xmmsc_result_t *res, cli_infos_t *infos, gchar *mark, gboolean all) { const gchar *s, *err; xmmsv_t *val; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); while (xmmsv_list_iter_valid (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); /* Skip hidden playlists if all is FALSE*/ if (xmmsv_get_string (entry, &s) && ((*s != '_') || all)) { /* Highlight active playlist */ if (mark && strcmp (s, mark) == 0) { g_printf ("* %s\n", s); } else { g_printf (" %s\n", s); } } xmmsv_list_iter_next (it); } } else { g_printf (_("Server error: %s\n"), err); } cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
void positions_print_list (xmmsc_result_t *res, playlist_positions_t *positions, column_display_t *coldisp, gboolean is_search) { cli_infos_t *infos = column_display_infos_get (coldisp); pl_pos_udata_t udata = { infos, coldisp, NULL, NULL, 0, 0}; xmmsv_t *val; GArray *entries; guint id; const gchar *err; /* FIXME: separate function or merge with list_print_row (lot of if(positions))? */ val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; column_display_prepare (coldisp); if (is_search) { column_display_print_header (coldisp); } entries = g_array_sized_new (FALSE, FALSE, sizeof (guint), xmmsv_list_get_size (val)); for (xmmsv_get_list_iter (val, &it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); if (xmmsv_get_uint (entry, &id)) { g_array_append_val (entries, id); } } udata.entries = entries; playlist_positions_foreach (positions, pos_print_row_cb, TRUE, &udata); } else { g_printf (_("Server error: %s\n"), err); } if (is_search) { column_display_print_footer (coldisp); } else { g_printf ("\n"); column_display_print_footer_totaltime (coldisp); } column_display_free (coldisp); g_array_free (entries, TRUE); cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
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 ); }
/** * Return a new value object which is a deep copy of the input value * * @param val #xmmsv_t to copy. * @return 1 the address to the new copy of the value. */ xmmsv_t * xmmsv_copy (xmmsv_t *val) { xmmsv_t *cur_val = NULL; xmmsv_type_t type; int64_t i; const char *s; float f; x_return_val_if_fail (val, 0); type = xmmsv_get_type (val); switch (type) { case XMMSV_TYPE_DICT: cur_val = duplicate_dict_value (val); break; case XMMSV_TYPE_LIST: cur_val = duplicate_list_value (val); break; case XMMSV_TYPE_INT64: xmmsv_get_int (val, &i); cur_val = xmmsv_new_int (i); break; case XMMSV_TYPE_FLOAT: xmmsv_get_float (val, &f); cur_val = xmmsv_new_float (f); break; case XMMSV_TYPE_STRING: xmmsv_get_string (val, &s); cur_val = xmmsv_new_string (s); break; case XMMSV_TYPE_ERROR: xmmsv_get_error (val, &s); cur_val = xmmsv_new_error (s); break; case XMMSV_TYPE_COLL: cur_val = duplicate_coll_value (val); break; case XMMSV_TYPE_BIN: cur_val = xmmsv_new_bin (val->value.bin.data, val->value.bin.len); break; case XMMSV_TYPE_BITBUFFER: cur_val = xmmsv_new_bitbuffer (); xmmsv_bitbuffer_put_data (cur_val, val->value.bit.buf, val->value.bit.len / 8); xmmsv_bitbuffer_goto (cur_val, xmmsv_bitbuffer_pos (val)); break; default: cur_val = xmmsv_new_none (); break; } assert (cur_val); return cur_val; }
void plugin_config_setup (xmmsc_connection_t *con) { xmmsc_result_t* res; xmmsv_t *val; const gchar *err, *name; /* call only once */ g_assert(plugins == NULL ); /* get translation of plugins/configs */ plugin_config_init_translation(); /* get list of available plugins */ res = xmmsc_main_list_plugins (con, XMMS_PLUGIN_TYPE_OUTPUT); /* we havn't entered async xmmsc_mainloop, so it's ok todo sync ops */ xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *elem; Plugin *plugin; xmmsv_list_iter_entry (it, &elem); xmmsv_dict_entry_get_string (elem, "shortname", &name); /* not blacklisted */ if ( g_strrstr( PLUGIN_BLACKLIST, name ) != NULL ) continue; plugin = g_slice_new( Plugin ); plugin->name = g_strdup(name); plugin->config = NULL; plugins = g_list_append(plugins, plugin); } } else { g_error ( "Server error: %s", err); } xmmsc_result_unref (res); /* get configuration options */ res = xmmsc_config_list_values (con ); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); xmmsv_dict_foreach( val, plugin_config_setup_parameter, NULL); }
void remove_cached_list (xmmsc_result_t *matching, cli_infos_t *infos) { /* FIXME: w00t at code copy-paste, please modularize */ xmmsc_result_t *rmres; guint plid, id; gint plsize; GArray *playlist; gint i; const gchar *err; xmmsv_t *val; val = xmmsc_result_get_value (matching); plsize = infos->cache->active_playlist->len; playlist = infos->cache->active_playlist; if (xmmsv_get_error (val, &err) || !xmmsv_is_list (val)) { g_printf (_("Error retrieving the media matching the pattern!\n")); } else { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); /* Loop on the playlist (backward, easier to remove) */ for (i = plsize - 1; i >= 0; i--) { plid = g_array_index (playlist, guint, i); /* Loop on the matched media */ for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); /* If both match, remove! */ if (xmmsv_get_uint (entry, &id) && plid == id) { rmres = xmmsc_playlist_remove_entry (infos->sync, NULL, i); xmmsc_result_wait (rmres); xmmsc_result_unref (rmres); break; } } } } cli_infos_loop_resume (infos); xmmsc_result_unref (matching); }
/* Dummy callback that resets the action status as finished. */ void done (xmmsc_result_t *res, cli_infos_t *infos) { const gchar *err; xmmsv_t *val; val = xmmsc_result_get_value (res); if (xmmsv_get_error (val, &err)) { g_printf (_("Server error: %s\n"), err); } cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
static void id_print_info (xmmsc_result_t *res, guint id, gchar *source) { xmmsv_t *val; const gchar *err; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_dict_foreach (val, propdict_dump, source); } else { g_printf (_("Server error: %s\n"), err); } xmmsc_result_unref (res); }
static VALUE c_get_error (VALUE self) { RbResult *res; xmmsv_t *val; const char *error; int ret; Data_Get_Struct (self, RbResult, res); val = xmmsc_result_get_value (res->real); ret = xmmsv_get_error (val, &error); return rb_str_new2 (ret ? error : ""); }
void add_list (xmmsc_result_t *matching, cli_infos_t *infos, gchar *playlist, gint pos) { /* FIXME: w00t at code copy-paste, please modularize */ xmmsc_result_t *insres; guint id; gint offset; const gchar *err; xmmsv_t *val; val = xmmsc_result_get_value (matching); offset = 0; if (xmmsv_get_error (val, &err) || !xmmsv_is_list (val)) { g_printf (_("Error retrieving the media matching the pattern!\n")); } else { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); /* Loop on the matched media */ for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); if (xmmsv_get_uint (entry, &id)) { insres = xmmsc_playlist_insert_id (infos->sync, playlist, pos + offset, id); xmmsc_result_wait (insres); xmmsc_result_unref (insres); offset++; } } } cli_infos_loop_resume (infos); xmmsc_result_unref (matching); }
/* Apply operation to an idlist */ void apply_ids (cli_infos_t *infos, xmmsc_result_t *res, idlist_command_t cmd) { const gchar *err; xmmsc_result_t *cmdres; xmmsv_t *val; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *entry; guint id; xmmsv_list_iter_entry (it, &entry); if (xmmsv_get_uint (entry, &id)) { switch (cmd) { case IDLIST_CMD_REHASH: cmdres = xmmsc_medialib_rehash (infos->sync, id); break; case IDLIST_CMD_REMOVE: cmdres = xmmsc_medialib_remove_entry (infos->sync, id); break; default: break; } xmmsc_result_wait (cmdres); xmmsc_result_unref (cmdres); } } } else { g_printf (_("Server error: %s\n"), err); } cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
void print_volume (xmmsc_result_t *res, cli_infos_t *infos, gchar *channel) { xmmsv_t *val; const gchar *err; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_dict_foreach (val, print_volume_entry, channel); } else { g_printf (_("Server error: %s\n"), err); } cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
static void print_server_stats (xmmsc_result_t *res) { gint uptime; const gchar *version, *err; xmmsv_t *val; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_dict_entry_get_string (val, "version", &version); xmmsv_dict_entry_get_int (val, "uptime", &uptime); g_printf ("uptime = %d\n" "version = %s\n", uptime, version); } else { g_printf ("Server error: %s\n", err); } }
void coll_show (cli_infos_t *infos, xmmsc_result_t *res) { const gchar *err; xmmsv_coll_t *coll; xmmsv_t *val; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_get_coll (val, &coll); coll_dump (coll, 0); } else { g_printf (_("Server error: %s\n"), err); } cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
void tickle (xmmsc_result_t *res, cli_infos_t *infos) { xmmsc_result_t *res2; const gchar *err; xmmsv_t *val; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { res2 = xmmsc_playback_tickle (infos->sync); xmmsc_result_wait (res2); done (res2, infos); } else { g_printf (_("Server error: %s\n"), err); cli_infos_loop_resume (infos); } xmmsc_result_unref (res); }
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; }
void list_print_info (xmmsc_result_t *res, cli_infos_t *infos) { xmmsc_result_t *infores = NULL; xmmsv_t *val; const gchar *err; guint id; gboolean first = true; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); while (xmmsv_list_iter_valid (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); if (xmmsv_get_uint (entry, &id)) { infores = xmmsc_medialib_get_info (infos->sync, id); xmmsc_result_wait (infores); if (!first) { g_printf ("\n"); } else { first = false; } id_print_info (infores, id, NULL); } xmmsv_list_iter_next (it); } } else { g_printf (_("Server error: %s\n"), err); } cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
void add_pls (xmmsc_result_t *plsres, cli_infos_t *infos, gchar *playlist, gint pos) { xmmsc_result_t *res; xmmsv_coll_t *coll; xmmsv_t *val; const char *err; val = xmmsc_result_get_value (plsres); if (!xmmsv_get_error (val, &err) && xmmsv_get_coll (val, &coll)) { res = xmmsc_playlist_add_idlist (infos->sync, playlist, coll); xmmsc_result_wait (res); xmmsc_result_unref (res); } else { g_printf (_("Server error: %s\n"), err); } xmmsc_result_unref (plsres); }
/* Callback for the reply from the other client. * This receives a client-to-client reply, which we expect to * contain an integer (the sum of the operands we sent), parses * this integer and prints it out. */ gint print_sum (xmmsv_t *c2c_reply, void *udata) { gint sum; const gchar *err; if (xmmsv_get_error (c2c_reply, &err)) { fprintf (stderr, "ERROR: %s\n", err); goto out; } /* Since we used xmmsc_result_notifier_set when setting up * this callback in the main funcion, it only receives the payload * of the reply, with no metadata. This means 'c2c_reply' is simply a * xmmsv_t integer, which we parse as such. * In contrast, we could have used xmmsc_result_notifier_set_raw * or xmmsc_result_notifier_set_c2c, in which case the contents of * 'c2c_reply' would be different. * Please consult the documentation for those functions for more * information. */ if (!xmmsv_get_int (c2c_reply, &sum)) { fprintf (stderr, "Can't get an integer out of the reply.\n"); goto out; } printf ("Sum is %d\n", sum); out: /* Return value for this callback doesn't matter, it's not * a broadcast nor a signal. * We leave the mainloop and exit the client. */ g_main_loop_quit ((GMainLoop *) udata); return TRUE; }
/* Returned tree must be freed by the caller */ static GTree * matching_ids_tree (xmmsc_result_t *matching) { xmmsv_t *val; guint id; GTree *list = NULL; const gchar *err; val = xmmsc_result_get_value (matching); if (xmmsv_get_error (val, &err) || !xmmsv_is_list (val)) { g_printf (_("Error retrieving the media matching the pattern!\n")); } else { xmmsv_list_iter_t *it; xmmsv_t *entry; list = g_tree_new_full (compare_uint, NULL, g_free, NULL); xmmsv_get_list_iter (val, &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_list_iter_entry (it, &entry); if (xmmsv_get_uint (entry, &id)) { guint *tid; tid = g_new (guint, 1); *tid = id; g_tree_insert (list, tid, tid); } } } return list; }
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); }
int main (int argc, char **argv) { xmmsc_result_t *res; xmmsv_t *configval; xmmsv_t *val; const char *errmsg; gchar *path = getenv ("XMMS_PATH"); connection = xmmsc_init ("xmms2-vistest"); if (!connection || !xmmsc_connect (connection, path)){ printf ("Couldn't connect to xmms2d: %s\n", xmmsc_get_last_error (connection)); exit (EXIT_FAILURE); } res = xmmsc_visualization_version (connection); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_get_error (val, &errmsg)) { puts (errmsg); exit (EXIT_FAILURE); } else { int32_t version; xmmsv_get_int (val, &version); /* insert the version you need here or instead of complaining, reduce your feature set to fit the version */ if (version < 1) { printf ("The server only supports formats up to version %d (needed is %d)!", version, 1); exit (EXIT_FAILURE); } } xmmsc_result_unref (res); res = xmmsc_visualization_init (connection); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_get_error (val, &errmsg)) { puts (errmsg); exit (EXIT_FAILURE); } vis = xmmsc_visualization_init_handle (res); configval = xmmsv_build_dict (XMMSV_DICT_ENTRY_STR ("type", "peak"), XMMSV_DICT_ENTRY_STR ("stereo", "1"), XMMSV_DICT_END); res = xmmsc_visualization_properties_set (connection, vis, configval); xmmsc_result_wait (res); val = xmmsc_result_get_value (res); if (xmmsv_get_error (val, &errmsg)) { puts (errmsg); exit (EXIT_FAILURE); } xmmsc_result_unref (res); xmmsv_unref (configval); while (!xmmsc_visualization_started (connection, vis)) { res = xmmsc_visualization_start (connection, vis); if (xmmsc_visualization_errored (connection, vis)) { printf ("Couldn't start visualization transfer: %s\n", xmmsc_get_last_error (connection)); exit (EXIT_FAILURE); } if (res) { xmmsc_result_wait (res); xmmsc_visualization_start_handle (connection, res); xmmsc_result_unref (res); } } /* using GTK mainloop */ mainloop = g_main_loop_new (NULL, FALSE); xmmsc_mainloop_gmain_init (connection); g_timeout_add_full (G_PRIORITY_DEFAULT, 20, draw_gtk, NULL, shutdown_gtk); g_main_loop_run (mainloop); /* not using GTK mainloop */ while (xmmsc_visualization_chunk_get (connection, vis, data, 0, 1000) != -1) { draw (); } putchar ('\n'); xmmsc_visualization_shutdown (connection, vis); if (connection) { xmmsc_unref (connection); } return 0; }
/* Abstract jump, use inc to choose the direction. */ static void list_jump_rel (xmmsc_result_t *res, cli_infos_t *infos, gint inc) { guint i; guint id; xmmsc_result_t *jumpres = NULL; xmmsv_t *val; const gchar *err; gint currpos; gint plsize; GArray *playlist; currpos = infos->cache->currpos; plsize = infos->cache->active_playlist->len; playlist = infos->cache->active_playlist; /* If no currpos, start jump from beginning */ if (currpos < 0) { currpos = 0; } val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err) && xmmsv_is_list (val)) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (val, &it); inc += plsize; /* magic trick so we can loop in either direction */ /* Loop on the playlist */ for (i = (currpos + inc) % plsize; i != currpos; i = (i + inc) % plsize) { /* Loop on the matched media */ for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); /* If both match, jump! */ if (xmmsv_get_uint (entry, &id) && g_array_index (playlist, guint, i) == id) { jumpres = xmmsc_playlist_set_next (infos->sync, i); xmmsc_result_wait (jumpres); tickle (jumpres, infos); goto finish; } } } } finish: /* No matching media found, don't jump */ if (!jumpres) { g_printf (_("No media matching the pattern in the playlist!\n")); cli_infos_loop_resume (infos); } xmmsc_result_unref (res); }
void list_print_row (xmmsc_result_t *res, xmmsv_coll_t *filter, column_display_t *coldisp, gboolean is_search) { /* FIXME: w00t at code copy-paste, please modularize */ cli_infos_t *infos = column_display_infos_get (coldisp); xmmsc_result_t *infores = NULL; xmmsv_t *val, *info; GTree *list = NULL; const gchar *err; guint id; gint i = 0; val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; column_display_prepare (coldisp); if (filter != NULL) { xmmsc_result_t *filres; filres = xmmsc_coll_query_ids (infos->sync, filter, NULL, 0, 0); xmmsc_result_wait (filres); if ((list = matching_ids_tree (filres)) == NULL) { goto finish; } } if (is_search) { column_display_print_header (coldisp); } xmmsv_get_list_iter (val, &it); while (xmmsv_list_iter_valid (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); if (xmmsv_get_uint (entry, &id) && (!list || g_tree_lookup (list, &id) != NULL)) { column_display_set_position (coldisp, i); id_coldisp_print_info (infos, coldisp, id); } xmmsv_list_iter_next (it); i++; } } else { g_printf (_("Server error: %s\n"), err); } if (is_search) { column_display_print_footer (coldisp); } else { g_printf ("\n"); column_display_print_footer_totaltime (coldisp); } finish: if (list) { g_tree_destroy (list); } column_display_free (coldisp); cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
int show_xmmsinfo_c(lua_State *L) { xmmsc_connection_t *connection; xmmsc_result_t *state; xmmsv_t *state_value; const char *err_buf; int32_t status; // string containing the current xmms2 state char *state_str; // initialize the Info struct struct Info i; // initialize the connection connection = xmmsc_init("xmmsinfo"); if (!connection) { fprintf(stderr, "No connection!\n"); return(EXIT_FAILURE); } // try to connect if (!xmmsc_connect(connection, getenv("XMMS_PATH"))) { fprintf(stderr, "Connection failed, %s\n", xmmsc_get_last_error(connection)); return(EXIT_FAILURE); } // get current xmms2 status state = xmmsc_playback_status(connection); xmmsc_result_wait(state); state_value = xmmsc_result_get_value(state); if(xmmsv_get_error(state_value, &err_buf)) { fprintf(stderr, "Error while asking for the connection status, %s\n", err_buf); } if(!xmmsv_get_int(state_value, &status)) { fprintf(stderr, "Couldn't get connection status, %d\n", status); } // 0 == stopped; 1 == playing; 2 == paused if(status == XMMS_PLAYBACK_STATUS_PLAY) { state_str = "playing"; } else if (status == XMMS_PLAYBACK_STATUS_PAUSE) { state_str = "paused"; } else { state_str = "stopped"; } i.state = state_str; // get current position in the playlist xmmsc_result_t *current_id; xmmsv_t *current_id_value; int32_t cur_id; current_id = xmmsc_playback_current_id(connection); xmmsc_result_wait(current_id); current_id_value = xmmsc_result_get_value(current_id); xmmsv_get_int(current_id_value, &cur_id); // initialize variables for the song info xmmsc_result_t *result; xmmsv_t *return_value; xmmsv_t *dict_entry; xmmsv_t *infos; const char *val; result = xmmsc_medialib_get_info(connection, cur_id); xmmsc_result_wait(result); return_value = xmmsc_result_get_value(result); if(xmmsv_get_error(return_value, &err_buf)) { fprintf(stderr, "Medialib returns error, %s\n", err_buf); return(EXIT_FAILURE); } infos = xmmsv_propdict_to_dict(return_value, NULL); if(!xmmsv_dict_get(infos, "artist", &dict_entry) || !xmmsv_get_string(dict_entry, &val)) { val = "No Artist"; } i.artist = val; if(!xmmsv_dict_get(infos, "album", &dict_entry) || !xmmsv_get_string(dict_entry, &val)) { val = "No Album"; } i.album = val; if(!xmmsv_dict_get(infos, "title", &dict_entry) || !xmmsv_get_string(dict_entry, &val)) { val = "No Title"; } i.song = val; i.id = cur_id; if(!xmmsv_dict_get(infos, "url", &dict_entry) || !xmmsv_get_string(dict_entry, &val)) { val = NULL; } i.uri = val; // push everything to lua lua_pushstring(L, i.state); lua_pushstring(L, i.artist); lua_pushstring(L, i.album); lua_pushstring(L, i.song); lua_pushinteger(L, i.id); lua_pushstring(L, i.uri); // clean up xmmsv_unref(infos); xmmsc_result_unref(result); xmmsc_result_unref(state); xmmsc_result_unref(current_id); xmmsc_unref(connection); return 6; }
void move_entries (xmmsc_result_t *matching, cli_infos_t *infos, gchar *playlist, gint pos) { xmmsc_result_t *movres, *lisres; guint id, curr; gint inc; gboolean up; GTree *list; xmmsv_t *lisval; const gchar *err; lisres = xmmsc_playlist_list_entries (infos->sync, playlist); xmmsc_result_wait (lisres); lisval = xmmsc_result_get_value (lisres); if (xmmsv_get_error (lisval, &err) || !xmmsv_is_list (lisval)) { g_printf (_("Error retrieving playlist entries\n")); } else { xmmsv_list_iter_t *it; xmmsv_t *entry; /* store matching mediaids in a tree (faster lookup) */ list = matching_ids_tree (matching); /* move matched playlist items */ curr = 0; inc = 0; up = TRUE; xmmsv_get_list_iter (lisval, &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_list_iter_entry (it, &entry); if (curr == pos) { up = FALSE; } if (xmmsv_get_uint (entry, &id) && g_tree_lookup (list, &id) != NULL) { if (up) { /* moving forward */ movres = xmmsc_playlist_move_entry (infos->sync, playlist, curr - inc, pos - 1); } else { /* moving backward */ movres = xmmsc_playlist_move_entry (infos->sync, playlist, curr, pos + inc); } xmmsc_result_wait (movres); xmmsc_result_unref (movres); inc++; } curr++; } g_tree_destroy (list); } finish: cli_infos_loop_resume (infos); xmmsc_result_unref (matching); xmmsc_result_unref (lisres); }
int xmmsv_bitbuffer_serialize_value (xmmsv_t *bb, xmmsv_t *v) { bool ret; int32_t i; const char *s; xmmsv_coll_t *c; const unsigned char *bc; unsigned int bl; xmmsv_type_t type; type = xmmsv_get_type (v); ret = _internal_put_on_bb_int32 (bb, type); if (!ret) return ret; switch (type) { case XMMSV_TYPE_ERROR: if (!xmmsv_get_error (v, &s)) { return false; } ret = _internal_put_on_bb_error (bb, s); break; case XMMSV_TYPE_INT32: if (!xmmsv_get_int (v, &i)) { return false; } ret = _internal_put_on_bb_int32 (bb, i); break; case XMMSV_TYPE_STRING: if (!xmmsv_get_string (v, &s)) { return false; } ret = _internal_put_on_bb_string (bb, s); break; case XMMSV_TYPE_COLL: if (!xmmsv_get_coll (v, &c)) { return false; } ret = _internal_put_on_bb_collection (bb, c); break; case XMMSV_TYPE_BIN: if (!xmmsv_get_bin (v, &bc, &bl)) { return false; } ret = _internal_put_on_bb_bin (bb, bc, bl); break; case XMMSV_TYPE_LIST: ret = _internal_put_on_bb_value_list (bb, v); break; case XMMSV_TYPE_DICT: ret = _internal_put_on_bb_value_dict (bb, v); break; case XMMSV_TYPE_NONE: break; default: x_internal_error ("Tried to serialize value of unsupported type"); return false; } return ret; }
void remove_list (xmmsc_result_t *matchres, xmmsc_result_t *plistres, cli_infos_t *infos, gchar *playlist) { /* FIXME: w00t at code copy-paste, please modularize */ xmmsc_result_t *rmres; guint plid, id, i; gint offset; const gchar *err; xmmsv_t *matchval, *plistval; matchval = xmmsc_result_get_value (matchres); plistval = xmmsc_result_get_value (plistres); if (xmmsv_get_error (matchval, &err) || !xmmsv_is_list (matchval)) { g_printf (_("Error retrieving the media matching the pattern!\n")); } else if (xmmsv_get_error (plistval, &err) || !xmmsv_is_list (plistval)) { g_printf (_("Error retrieving the playlist!\n")); } else { xmmsv_list_iter_t *matchit, *plistit; /* FIXME: Can we use a GList to remove more safely in the rev order? */ offset = 0; i = 0; xmmsv_get_list_iter (matchval, &matchit); xmmsv_get_list_iter (plistval, &plistit); /* Loop on the playlist */ for (xmmsv_list_iter_first (plistit); xmmsv_list_iter_valid (plistit); xmmsv_list_iter_next (plistit)) { xmmsv_t *plist_entry; xmmsv_list_iter_entry (plistit, &plist_entry); if (!xmmsv_get_uint (plist_entry, &plid)) { plid = 0; /* failed to get id, should not happen */ } /* Loop on the matched media */ for (xmmsv_list_iter_first (matchit); xmmsv_list_iter_valid (matchit); xmmsv_list_iter_next (matchit)) { xmmsv_t *match_entry; xmmsv_list_iter_entry (matchit, &match_entry); /* If both match, jump! */ if (xmmsv_get_uint (match_entry, &id) && plid == id) { rmres = xmmsc_playlist_remove_entry (infos->sync, playlist, i - offset); xmmsc_result_wait (rmres); xmmsc_result_unref (rmres); offset++; break; } } i++; } } cli_infos_loop_resume (infos); xmmsc_result_unref (matchres); xmmsc_result_unref (plistres); }
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); }