/* Called on server disconnection. We can keep the loop running. */ static gint cli_infos_disconnect_callback (xmmsv_t *val, void *userdata) { cli_infos_t *infos = (cli_infos_t *) userdata; xmmsc_unref (infos->conn); xmmsc_unref (infos->sync); infos->conn = NULL; infos->sync = NULL; readline_status_mode_exit (); cli_infos_loop_resume (infos); return TRUE; }
static void c_free (RbXmmsClient *xmms) { if (xmms->real && !xmms->deleted) xmmsc_unref (xmms->real); free (xmms); }
int main (int argc, char **argv) { GMainLoop *ml; xmmsv_t *operands; xmmsc_result_t *result; xmmsc_connection_t *connection; if (argc != 4) { fprintf (stderr, "Usage: %s service-id op1 op2\n", argv[0]); return EXIT_FAILURE; } /* Connect as usual. */ connection = xmmsc_init ("sumclient"); 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); } ml = g_main_loop_new (NULL, FALSE); /* Build a list of two operands for sumservice (tut9). */ operands = xmmsv_build_list (xmmsv_new_int (atoi(argv[2])), xmmsv_new_int (atoi(argv[3])), XMMSV_LIST_END); /* And send the list to the sumservice. * We use the reply policy of only expecting a single reply, * which means the receiving client will get an error from * the server if it attempts to reply to this message more * than once. */ result = xmmsc_c2c_send (connection, atoi(argv[1]), XMMS_C2C_REPLY_POLICY_SINGLE_REPLY, operands); xmmsv_unref (operands); xmmsc_result_notifier_set (result, print_sum, ml); xmmsc_result_unref (result); xmmsc_mainloop_gmain_init (connection); g_main_loop_run (ml); xmmsc_unref (connection); return EXIT_SUCCESS; }
/** Free all memory owned by the cache. */ void cli_cache_free (cli_cache_t *cache) { if (cache->conn != NULL) xmmsc_unref (cache->conn); g_free (cache->active_playlist_name); xmmsv_unref (cache->active_playlist); g_free (cache); }
/* Called on server disconnection. We can keep the loop running. */ static gint cli_infos_disconnect_callback (xmmsv_t *val, void *userdata) { cli_infos_t *infos = (cli_infos_t *) userdata; xmmsc_unref (infos->conn); xmmsc_unref (infos->sync); infos->conn = NULL; infos->sync = NULL; if (infos->status == CLI_ACTION_STATUS_REFRESH) { status_refresh (infos, infos->status_entry, FALSE, TRUE); readline_status_mode_exit (); } cli_infos_loop_resume (infos); return TRUE; }
/* Called on server disconnection. We can keep the loop running. */ static gint cli_context_disconnect_callback (xmmsv_t *val, void *userdata) { cli_context_t *ctx = (cli_context_t *) userdata; xmmsc_unref (ctx->conn); xmmsc_unref (ctx->sync); ctx->conn = NULL; ctx->sync = NULL; if (ctx->status == CLI_ACTION_STATUS_REFRESH) { status_refresh (ctx->status_entry, FALSE, TRUE); readline_status_mode_exit (); } cli_context_loop_resume (ctx); return TRUE; }
static void updater_destroy (updater_t *updater) { g_return_if_fail (updater); g_return_if_fail (updater->watchers); g_return_if_fail (updater->conn); g_hash_table_destroy (updater->watchers); xmmsc_unref (updater->conn); g_free (updater); }
void xmmsc_mainloop_gmain_shutdown (xmmsc_connection_t *c, void *data) { g_return_if_fail (data != NULL); xmmsc_glib_watch_t *watch = (xmmsc_glib_watch_t *) data; g_source_remove (watch->source_id); xmmsc_unref (watch->conn); g_free (watch); }
Client::~Client() { if( mainloop_ ) { // Also deletes listener_ delete mainloop_; } if( quitSignal_ ) { delete quitSignal_; } if( conn_ ) { xmmsc_unref( conn_ ); } }
static VALUE c_delete (VALUE self) { RbXmmsClient *xmms = NULL; Data_Get_Struct (self, RbXmmsClient, xmms); CHECK_DELETED (xmms); xmmsc_unref (xmms->real); xmms->deleted = true; return Qnil; }
void Client::dcHandler() { connected_ = false; if( mainloop_ && listener_ ) { dynamic_cast<MainLoop*>(mainloop_)->removeListener( listener_ ); delete listener_; listener_ = 0; } else if( mainloop_ ) { delete mainloop_; mainloop_ = 0; } SignalHolder::getInstance().deleteAll(); xmmsc_unref( conn_ ); conn_ = 0; }
void cli_context_free (cli_context_t *ctx) { if (ctx->conn) { xmmsc_unref (ctx->conn); } if (ctx->mode == CLI_EXECUTION_MODE_SHELL) { readline_free (); } command_trie_free (ctx->commands); cli_cache_free (ctx->cache); configuration_free (ctx->config); cmdnames_free (ctx->cmdnames); g_free (ctx); }
int main (int argc, char **argv) { xmmsc_connection_t *conn; gchar *path; gchar *gp = NULL; gchar **s; gchar **ipcsplit; guint port; int i; printf ("Starting XMMS2 mDNS Agent...\n"); path = getenv ("XMMS_PATH_FULL"); if (!path) { printf ("Sorry you need XMMS_PATH_FULL set\n"); exit (1); } ipcsplit = g_strsplit (path, ";", 0); for (i = 0; ipcsplit[i]; i++) { if (g_ascii_strncasecmp (ipcsplit[i], "tcp://", 6) == 0) { gp = ipcsplit[i]; } } if (!gp) { printf ("Need to have a socket listening to TCP before we can do that!"); exit (1); } s = g_strsplit (gp, ":", 0); if (s && s[2]) { port = strtol (s[2], NULL, 10); } else { port = XMMS_DEFAULT_TCP_PORT; } conn = xmmsc_init ("xmms2-mdns"); if (!conn) { printf ("Could not init xmmsc_connection!\n"); exit (1); } if (!xmmsc_connect (conn, gp)) { printf ("Could not connect to xmms2d: %s\n", xmmsc_get_last_error (conn)); exit (1); } ml = g_main_loop_new (NULL, FALSE); XMMS_CALLBACK_SET (conn, xmmsc_broadcast_quit, handle_quit, ml); xmmsc_disconnect_callback_set (conn, disconnected, NULL); register_service (port); xmmsc_mainloop_gmain_init (conn); g_main_loop_run (ml); DNSServiceRefDeallocate (g_sdref); xmmsc_unref (conn); printf ("XMMS2-mDNS shutting down...\n"); return 0; }
gboolean cli_context_connect (cli_context_t *ctx, gboolean autostart) { gchar *path; xmmsc_result_t *res; /* Open Async connection first */ ctx->conn = xmmsc_init (CLI_CLIENTNAME); if (!ctx->conn) { g_printf (_("Could not init connection!\n")); return FALSE; } path = configuration_get_string (ctx->config, "ipcpath"); if (!xmmsc_connect (ctx->conn, path)) { if (!autostart) { /* Failed to connect, but don't autostart */ xmmsc_unref (ctx->conn); ctx->conn = NULL; return FALSE; } else if (!cli_context_autostart (ctx, path)) { /* Autostart failed, abort now */ if (path) { g_printf (_("Could not connect to server at '%s'!\n"), path); } else { g_printf (_("Could not connect to server at default path!\n")); } xmmsc_unref (ctx->conn); ctx->conn = NULL; return FALSE; } } /* Sync connection */ ctx->sync = xmmsc_init (CLI_CLIENTNAME "-sync"); if (!ctx->sync) { g_printf (_("Could not init sync connection!\n")); return FALSE; } if (!xmmsc_connect (ctx->sync, path)) { if (path) { g_printf (_("Could not connect to server at '%s'!\n"), path); } else { g_printf (_("Could not connect to server at default path!\n")); } xmmsc_unref (ctx->conn); xmmsc_unref (ctx->sync); ctx->conn = NULL; ctx->sync = NULL; return FALSE; } /* Reset the connection state on server quit */ res = xmmsc_broadcast_quit (ctx->conn); xmmsc_disconnect_callback_set (ctx->conn, disconnect_callback, ctx); xmmsc_result_notifier_set (res, &cli_context_disconnect_callback, ctx); xmmsc_result_unref (res); cli_cache_start (ctx->cache, ctx->conn); return TRUE; }
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; }
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); }
gboolean cli_infos_connect (cli_infos_t *infos, gboolean autostart) { gchar *path; xmmsc_result_t *res; /* Open Async connection first */ infos->conn = xmmsc_init (CLI_CLIENTNAME); if (!infos->conn) { g_printf (_("Could not init connection!\n")); return FALSE; } path = getenv ("XMMS_PATH"); if (!xmmsc_connect (infos->conn, path)) { if (!autostart) { /* Failed to connect, but don't autostart */ xmmsc_unref (infos->conn); infos->conn = NULL; return FALSE; } else if (!cli_infos_autostart (infos, path)) { /* Autostart failed, abort now */ if (path) { g_printf (_("Could not connect to server at '%s'!\n"), path); } else { g_printf (_("Could not connect to server at default path!\n")); } xmmsc_unref (infos->conn); infos->conn = NULL; return FALSE; } } /* Sync connection */ infos->sync = xmmsc_init (CLI_CLIENTNAME "-sync"); if (!infos->sync) { g_printf (_("Could not init sync connection!\n")); return FALSE; } if (!xmmsc_connect (infos->sync, path)) { if (path) { g_printf (_("Could not connect to server at '%s'!\n"), path); } else { g_printf (_("Could not connect to server at default path!\n")); } xmmsc_unref (infos->conn); xmmsc_unref (infos->sync); infos->conn = NULL; infos->sync = NULL; return FALSE; } /* Reset the connection state on server quit */ res = xmmsc_broadcast_quit (infos->conn); xmmsc_result_notifier_set (res, &cli_infos_disconnect_callback, infos); xmmsc_result_unref (res); cli_cache_start (infos); return TRUE; }
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; }
int main (int argc, char **argv) { xmmsc_connection_t *conn; GMainLoop *ml; gchar *path; printf ("Starting XMMS2 phone home agent...\n"); path = getenv ("XMMS_PATH"); conn = xmmsc_init ("xmms2-et"); if (!conn) { printf ("Could not init xmmsc_connection!\n"); exit (1); } if (!xmmsc_connect (conn, path)) { printf ("Could not connect to xmms2d: %s\n", xmmsc_get_last_error (conn)); exit (1); } output_plugin = g_strdup ("unknown"); get_systemname (); send_socket = socket (PF_INET, SOCK_DGRAM, 0); ml = g_main_loop_new (NULL, FALSE); memset (&dest_addr, 0, sizeof (dest_addr)); dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons (DEST_PORT); inet_aton (DEST_IP, &dest_addr.sin_addr); start_time = time (NULL); XMMS_CALLBACK_SET (conn, xmmsc_broadcast_playback_current_id, handle_current_id, conn); XMMS_CALLBACK_SET (conn, xmmsc_main_stats, handle_stats, NULL); XMMS_CALLBACK_SET (conn, xmmsc_broadcast_config_value_changed, handle_config, NULL); XMMS_CALLBACK_SET (conn, xmmsc_broadcast_quit, handle_quit, ml); XMMS_CALLBACK_SET (conn, xmmsc_signal_mediainfo_reader_unindexed, handle_mediainfo_reader, NULL); { xmmsc_result_t *res; res = xmmsc_config_get_value (conn, "output.plugin"); xmmsc_result_notifier_set (res, handle_config_val, NULL); xmmsc_result_unref (res); } xmmsc_disconnect_callback_set (conn, disconnected, NULL); xmmsc_mainloop_gmain_init (conn); g_main_loop_run (ml); xmmsc_unref (conn); printf ("XMMS2-ET shutting down...\n"); send_msg ("Clean shutdown", NULL); return 0; }
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); }