Ejemplo n.º 1
0
static void
updater_subscribe_config (updater_t *updater)
{
	xmmsc_result_t *res;
	const gchar *default_directory;

	g_return_if_fail (updater);
	g_return_if_fail (updater->conn);

	default_directory = g_get_user_special_dir (G_USER_DIRECTORY_MUSIC);

	if (!default_directory) {
		default_directory = "";
	}

	res = xmmsc_config_register_value (updater->conn,
	                                   "mlibupdater.watch_dirs",
	                                   default_directory);

	xmmsc_result_notifier_set (res, updater_config_register, updater);
	xmmsc_result_unref (res);

	res = xmmsc_broadcast_config_value_changed (updater->conn);
	xmmsc_result_notifier_set (res, updater_config_changed, updater);
	xmmsc_result_unref (res);
}
Ejemplo n.º 2
0
int 
main (int argc, char **argv)
{
	GIOChannel *gio;
	GMainLoop *ml;
	gchar *path;
	gchar *tmp;
	xmmsc_connection_t *conn;
	xmmsc_result_t *res;
	xmonitor_t *mon;
	gint fd;

	conn = xmmsc_init ("xmms-medialib-updater");
	path = getenv ("XMMS_PATH");
	if (!xmmsc_connect (conn, path)) {
		ERR ("Could not connect to xmms2d %s", xmmsc_get_last_error (conn));
		return EXIT_FAILURE;
	}

	ml = g_main_loop_new (NULL, FALSE);
	xmmsc_mainloop_gmain_init (conn);
	xmmsc_disconnect_callback_set (conn, quit, ml);

	mon = g_new0 (xmonitor_t, 1);
	fd = monitor_init (mon);
	mon->conn = conn;

	if (fd == -1) {
		ERR ("Couldn't initalize monitor");
		return EXIT_FAILURE;
	}


	tmp = getenv("XMMS_DEBUG");
	if (!tmp) {
		g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE | G_LOG_FLAG_RECURSION, 
				   message_handler, NULL);
	}

	gio = g_io_channel_unix_new (fd);
	g_io_add_watch (gio, G_IO_IN, s_callback, mon);

	res = xmmsc_configval_register (conn, "mlibupdater.watch_dirs", "");
	xmmsc_result_notifier_set (res, handle_configval, mon);
	xmmsc_result_unref (res);

	res = xmmsc_broadcast_configval_changed (conn);
	xmmsc_result_notifier_set (res, handle_config_changed, mon);
	xmmsc_result_unref (res);

	g_main_loop_run (ml);

	return EXIT_SUCCESS;
}
Ejemplo n.º 3
0
static void
updater_remove_directory (updater_t *updater, GFile *file)
{
	xmmsc_result_t *res;
	xmmsv_t *univ, *coll;
	gchar *path, *pattern, *encoded;

	path = g_file_get_path (file);
	encoded = xmmsv_encode_url (path);
	g_free (path);

	pattern = g_strdup_printf ("file://%s/*", encoded);
	g_free (encoded);

	univ = xmmsv_new_coll (XMMS_COLLECTION_TYPE_UNIVERSE);
	coll = xmmsv_new_coll (XMMS_COLLECTION_TYPE_MATCH);

	xmmsv_coll_add_operand (coll, univ);
	xmmsv_coll_attribute_set_string (coll, "field", "url");
	xmmsv_coll_attribute_set_string (coll, "value", pattern);
	xmmsv_coll_attribute_set_string (coll, "case-sensitive", "true");

	g_debug ("remove '%s' from mlib", pattern);

	res = xmmsc_coll_query_ids (updater->conn, coll, NULL, 0, 0);
	xmmsc_result_notifier_set (res, updater_remove_directory_by_id, updater);
	xmmsc_result_unref (res);

	xmmsv_unref (coll);
	xmmsv_unref (univ);

	g_free (pattern);
}
Ejemplo n.º 4
0
static void
do_watch_dir (xmonitor_t *mon, const gchar *dirs)
{
	xmmsc_result_t *res;
	GList *n;

	DBG ("We are going to watch '%s'", dirs);

	for (n = mon->dir_list; n; n = g_list_next (n)) {
		monitor_del_dir (mon, n->data);
		g_free (n->data);
	}

	if (mon->dir_list) {
		g_list_free (mon->dir_list);
		mon->dir_list = NULL;
	}

	if (strlen (dirs) < 1) {
		mon->watch_dir = NULL;
		return;
	} else {
		mon->watch_dir = g_strdup (dirs);
	}

	/* Make sure that nothing changed while we where away! */
	res = xmmsc_medialib_path_import (mon->conn, mon->watch_dir);
	xmmsc_result_notifier_set (res, handle_addpath, mon);
	xmmsc_result_unref (res);
}
Ejemplo n.º 5
0
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;

}
Ejemplo n.º 6
0
static gint
update_active_playlist (xmmsv_t *val, void *udata)
{
	cli_infos_t *infos = (cli_infos_t *) udata;
	cli_cache_t *cache = infos->cache;
	xmmsc_result_t *refres;
	gint pos, newpos, type;
	gint id;
	const gchar *name;

	xmmsv_dict_entry_get_int (val, "type", &type);
	xmmsv_dict_entry_get_int (val, "position", &pos);
	xmmsv_dict_entry_get_int (val, "id", &id);
	xmmsv_dict_entry_get_string (val, "name", &name);

	/* Active playlist not changed, nevermind */
	if (strcmp (name, cache->active_playlist_name) != 0) {
		return TRUE;
	}

	/* Apply changes to the cached playlist */
	switch (type) {
	case XMMS_PLAYLIST_CHANGED_ADD:
		g_array_append_val (cache->active_playlist, id);
		break;

	case XMMS_PLAYLIST_CHANGED_INSERT:
		g_array_insert_val (cache->active_playlist, pos, id);
		break;

	case XMMS_PLAYLIST_CHANGED_MOVE:
		xmmsv_dict_entry_get_int (val, "newposition", &newpos);
		g_array_remove_index (cache->active_playlist, pos);
		g_array_insert_val (cache->active_playlist, newpos, id);
		break;

	case XMMS_PLAYLIST_CHANGED_REMOVE:
		g_array_remove_index (cache->active_playlist, pos);
		break;

	case XMMS_PLAYLIST_CHANGED_SHUFFLE:
	case XMMS_PLAYLIST_CHANGED_SORT:
	case XMMS_PLAYLIST_CHANGED_CLEAR:
		/* Oops, reload the whole playlist */
		refres = xmmsc_playlist_list_entries (infos->conn, XMMS_ACTIVE_PLAYLIST);
		xmmsc_result_notifier_set (refres, &refresh_active_playlist, infos->cache);
		xmmsc_result_unref (refres);
		freshness_requested (&cache->freshness_active_playlist);
		break;
	}

	return TRUE;
}
Ejemplo n.º 7
0
/** Fill the cache with initial (current) data, setup listeners. */
void
cli_cache_start (cli_infos_t *infos)
{
	xmmsc_result_t *res;

	/* Setup async listeners */
	res = xmmsc_broadcast_playlist_current_pos (infos->conn);
	xmmsc_result_notifier_set (res, &refresh_currpos, infos->cache);
	xmmsc_result_unref (res);

	res = xmmsc_broadcast_playback_current_id (infos->conn);
	xmmsc_result_notifier_set (res, &refresh_currid, infos->cache);
	xmmsc_result_unref (res);

	res = xmmsc_broadcast_playback_status (infos->conn);
	xmmsc_result_notifier_set (res, &refresh_playback_status, infos->cache);
	xmmsc_result_unref (res);

	res = xmmsc_broadcast_playlist_changed (infos->conn);
	xmmsc_result_notifier_set (res, &update_active_playlist, infos);
	xmmsc_result_unref (res);

	res = xmmsc_broadcast_playlist_loaded (infos->conn);
	xmmsc_result_notifier_set (res, &reload_active_playlist, infos);
	xmmsc_result_unref (res);

	res = xmmsc_broadcast_collection_changed (infos->conn);
	xmmsc_result_notifier_set (res, &update_active_playlist_name, infos);
	xmmsc_result_unref (res);

	/* Setup one-time value fetchers, for init */
	cli_cache_refresh (infos);
}
Ejemplo n.º 8
0
static void
handle_file_changed (xmonitor_t *mon, gchar *filename)
{
	xmmsc_result_t *res;
	gchar tmp[MON_FILENAME_MAX];

	g_snprintf (tmp, MON_FILENAME_MAX, "file://%s", filename);

	res = xmmsc_medialib_get_id (mon->conn, tmp);
	xmmsc_result_notifier_set (res, handle_mlib_update, mon);
	xmmsc_result_unref (res);
	DBG ("update file in medialib");
}
Ejemplo n.º 9
0
static int
handle_current_id (xmmsv_t *v, void *userdata)
{
	xmmsc_connection_t *conn = userdata;
	xmmsc_result_t *res2;
	gint current_id;

	if (xmmsv_get_int (v, &current_id)) {
		res2 = xmmsc_medialib_get_info (conn, current_id);
		xmmsc_result_notifier_set (res2, handle_mediainfo, conn);
		xmmsc_result_unref (res2);
	}

	return TRUE; /* keep broadcast alive */
}
Ejemplo n.º 10
0
static int
handle_configval (xmmsv_t *v, void *data)
{
	xmmsc_result_t *res2;
	xmonitor_t *mon = data;
	const gchar *val;

	if (!xmmsv_get_string (v, &val)) {
		ERR ("Couldn't register value in server!");
		return FALSE;
	}

	res2 = xmmsc_configval_get (mon->conn, val);
	xmmsc_result_notifier_set (res2, handle_watch_dirs, mon);
	xmmsc_result_unref (res2);

	return FALSE;
}
Ejemplo n.º 11
0
/*
 * call-seq:
 *  res.notifier { |res| }
 *
 * Sets the block that's executed when _res_ is handled.
 * Used by asyncronous results only.
 */
static VALUE
c_notifier_set (VALUE self)
{
	VALUE callback;
	RbResult *res = NULL;
	RbXmmsClient *xmms = NULL;

	Data_Get_Struct (self, RbResult, res);

	if (!rb_block_given_p ())
		return Qnil;

	callback = rb_block_proc ();

	Data_Get_Struct (res->xmms, RbXmmsClient, xmms);
	rb_ary_push (xmms->result_callbacks, callback);

	xmmsc_result_notifier_set (res->real, on_signal, (void *) callback);

	return Qnil;
}
Ejemplo n.º 12
0
static void
updater_rehash_file (updater_t *updater, GFile *file)
{
	xmmsc_result_t *res;
	gchar *path, *url;

	g_return_if_fail (updater);
	g_return_if_fail (updater->conn);
	g_return_if_fail (file);

	path = g_file_get_path (file);
	url = g_strdup_printf ("file://%s", path);
	g_free (path);

	g_debug ("resolving entry '%s'", url);

	res = xmmsc_medialib_get_id (updater->conn, url);
	xmmsc_result_notifier_set (res, updater_rehash_file_by_id, updater);
	xmmsc_result_unref (res);

	g_free (url);
}
Ejemplo n.º 13
0
static gint
reload_active_playlist (xmmsv_t *val, void *udata)
{
	cli_infos_t *infos = (cli_infos_t *) udata;
	xmmsc_result_t *refres;
	const gchar *buf;

	/* FIXME: Also listen to playlist renames, in case the active PL is renamed! */
	/* Refresh playlist name */
	if (xmmsv_get_string (val, &buf)) {
		g_free (infos->cache->active_playlist_name);
		infos->cache->active_playlist_name = g_strdup (buf);
	}

	/* Get all the entries again */
	refres = xmmsc_playlist_list_entries (infos->conn, XMMS_ACTIVE_PLAYLIST);
	xmmsc_result_notifier_set (refres, &refresh_active_playlist, infos->cache);
	xmmsc_result_unref (refres);
	freshness_requested (&infos->cache->freshness_active_playlist);

	return TRUE;
}
Ejemplo n.º 14
0
static int
updater_config_register (xmmsv_t *value, void *udata)
{
	xmmsc_result_t *res;
	const gchar *conf;
	updater_t *updater;

	updater = (updater_t *) udata;

	g_return_val_if_fail (updater, FALSE);

	if (!xmmsv_get_string (value, &conf)) {
		g_error ("Failed to register config value\n");
		return FALSE;
	}

	res = xmmsc_config_get_value (updater->conn, conf);
	xmmsc_result_notifier_set (res, updater_config_get, updater);
	xmmsc_result_unref (res);

	return FALSE;
}
Ejemplo n.º 15
0
static void
handle_file_del (xmonitor_t *mon, gchar *filename)
{
	xmmsc_result_t *res;
	xmmsv_coll_t *univ, *coll;
	gchar tmp[MON_FILENAME_MAX];

	g_snprintf (tmp, MON_FILENAME_MAX, "file://%s%%", filename);

	univ = xmmsv_coll_universe ();
	coll = xmmsv_coll_new (XMMS_COLLECTION_TYPE_MATCH);
	xmmsv_coll_add_operand (coll, univ);
	xmmsv_coll_attribute_set (coll, "field", "url");
	xmmsv_coll_attribute_set (coll, "value", tmp);

	res = xmmsc_coll_query_ids (mon->conn, coll, NULL, 0, 0);

	DBG ("remove '%s' from mlib", tmp);
	xmmsc_result_notifier_set (res, handle_remove_from_mlib, mon);
	xmmsc_result_unref (res);
	xmmsv_coll_unref (coll);
	xmmsv_coll_unref (univ);
}
Ejemplo n.º 16
0
/** Fill the cache with initial (current) data, setup listeners. */
void
cli_cache_start (cli_cache_t *cache, xmmsc_connection_t *conn)
{
    xmmsc_result_t *res;

    g_return_if_fail (cache->conn == NULL);

    cache->conn = xmmsc_ref (conn);

    /* Setup async listeners */
    res = xmmsc_broadcast_playlist_current_pos (conn);
    xmmsc_result_notifier_set (res, &refresh_currpos, cache);
    xmmsc_result_unref (res);

    res = xmmsc_broadcast_playback_current_id (conn);
    xmmsc_result_notifier_set (res, &refresh_currid, cache);
    xmmsc_result_unref (res);

    res = xmmsc_broadcast_playback_status (conn);
    xmmsc_result_notifier_set (res, &refresh_playback_status, cache);
    xmmsc_result_unref (res);

    res = xmmsc_broadcast_playlist_changed (conn);
    xmmsc_result_notifier_set (res, &update_active_playlist, cache);
    xmmsc_result_unref (res);

    res = xmmsc_broadcast_playlist_loaded (conn);
    xmmsc_result_notifier_set (res, &reload_active_playlist, cache);
    xmmsc_result_unref (res);

    res = xmmsc_broadcast_collection_changed (conn);
    xmmsc_result_notifier_set (res, &update_active_playlist_name, cache);
    xmmsc_result_unref (res);

    /* Setup one-time value fetchers, for init */
    cli_cache_refresh (cache);
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
int
main (int argc, char **argv)
{
	/* The mainloop we should use later */
	GMainLoop *ml;

	/*
	 * The first part of this program is
	 * commented on in tut1.c
	 */
	xmmsc_connection_t *connection;
	xmmsc_result_t *result;

	/*
	 * In an async client we still connect as
	 * normal. Read up on this in earlier
	 * tutorials if you need.
	 */
	connection = xmmsc_init ("tutorial6");
	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);
	}

	/*
	 * Initialize the mainloop, for more information about GLib mainloop
	 * see the GTK docs.
	 */
	ml = g_main_loop_new (NULL, FALSE);

	/*
	 * We issue two async commands to restart playback.
	 * Since we don't want to set a notifier for those,
	 * we can free the result immediately.
	 */
	xmmsc_result_unref (xmmsc_playback_stop (connection));
	xmmsc_result_unref (xmmsc_playback_start (connection));

	printf ("Playtime: \n");
	result = xmmsc_signal_playback_playtime (connection);
	xmmsc_result_notifier_set (result, my_playtime, ml);
	xmmsc_result_unref (result);

	/*
	 * As you see we do it pretty much the same way that we did in tut2, but
	 * instead of being able to access the current id directly (as we would
	 * have if we where blocking) we need to wait until xmms calls our
	 * my_current_id function. This will keep your GUI from hanging while
	 * waiting for xmms2 to answer your command.
	 *
	 * In order to make xmmsclient call your callback functions we need to put
	 * the fd of the connection into the mainloop of our program. For your
	 * convenience the xmmsclient lib ships with automatic integration with
	 * GMainLoop. We just need to link with xmmsclient-glib and do the following
	 * call to make it work.
	 */
	xmmsc_mainloop_gmain_init (connection);

	/*
	 * We are now all set to go. Just run the main loop and watch the magic.
	 */

	g_main_loop_run (ml);

	return EXIT_SUCCESS;

}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
int
main (int argc, char **argv)
{
	/* The mainloop we should use later */
	GMainLoop *ml;

	/*
	 * The first part of this program is
	 * commented on in tut1.c
	 */
	xmmsc_connection_t *connection;
	xmmsc_result_t *result;

	/*
	 * In an async client we still connect as
	 * normal. Read up on this in earlier
	 * tutorials if you need.
	 */
	connection = xmmsc_init ("tutorial6");
	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);
	}

	/*
	 * Initialize the mainloop, for more information about GLib mainloop
	 * see the GTK docs.
	 */
	ml = g_main_loop_new (NULL, FALSE);

	/*
	 * The big difference between a sync client and an async client is that the
	 * async client works with callbacks. When you send a command and get an
	 * xmmsc_result_t back you should set up a callback for it and directly
	 * unref it. This means we can't do syncronous operations on this connection.
	 *
	 * In simple cases you can use the XMMS_CALLBACK_SET macro, but in order to
	 * be verbose here I do it all manually. Let's ask for the current id
	 * in an async way instead of the sync way as we did in tut2.
	 */

	result = xmmsc_playback_current_id (connection);
	xmmsc_result_notifier_set (result, my_current_id, ml);
	xmmsc_result_unref (result);

	/*
	 * As you see we do it pretty much the same way that we did in tut2, but
	 * instead of being able to access the current id directly (as we would
	 * have if we where blocking) we need to wait until xmms calls our
	 * my_current_id function. This will keep your GUI from hanging while
	 * waiting for xmms2 to answer your command.
	 *
	 * In order to make xmmsclient call your callback functions we need to put
	 * the fd of the connection into the mainloop of our program. For your
	 * convenience the xmmsclient lib ships with automatic integration with
	 * GMainLoop. We just need to link with xmmsclient-glib and do the following
	 * call to make it work.
	 */
	xmmsc_mainloop_gmain_init (connection);

	/*
	 * We are now all set to go. Just run the main loop and watch the magic.
	 */

	g_main_loop_run (ml);

	return EXIT_SUCCESS;

}