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); }
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; }
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); }
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); }
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; }
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; }
/** 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); }
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"); }
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, ¤t_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 */ }
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; }
/* * 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; }
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); }
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; }
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; }
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); }
/** 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); }
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) { /* 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; }
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 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) { /* 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; }