Пример #1
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;

}
Пример #2
0
static xmmsv_t *
xmms_medialib_entry_to_tree (xmms_medialib_session_t *session,
                             xmms_medialib_entry_t entry)
{
	s4_resultset_t *set;
	s4_val_t *song_id;
	xmmsv_t *ret, *id;
	gint i;

	song_id = s4_val_new_int (entry);
	set = xmms_medialib_filter (session, "song_id", song_id, S4_COND_PARENT,
	                            NULL, NULL, S4_FETCH_PARENT | S4_FETCH_DATA);
	s4_val_free (song_id);

	ret = xmmsv_new_dict ();

	for (i = 0; i < s4_resultset_get_rowcount (set); i++) {
		const s4_result_t *res;

		res = s4_resultset_get_result (set, 0, 0);
		while (res != NULL) {
			xmmsv_t *v_entry = NULL;
			const s4_val_t *val;
			const char *s;
			gint32 i;

			val = s4_result_get_val (res);
			if (s4_val_get_str (val, &s)) {
				v_entry = xmmsv_new_string (s);
			} else if (s4_val_get_int (val, &i)) {
				v_entry = xmmsv_new_int (i);
			}

			xmms_medialib_tree_add_tuple (ret, s4_result_get_key (res),
			                              s4_result_get_src (res), v_entry);
			xmmsv_unref (v_entry);

			res = s4_result_next (res);
		}
	}

	s4_resultset_free (set);

	id = xmmsv_new_int (entry);
	xmms_medialib_tree_add_tuple (ret, "id", "server", id);
	xmmsv_unref (id);

	return ret;
}
Пример #3
0
/** List a playlist */
static GList *
xmms_playlist_client_list_entries (xmms_playlist_t *playlist, const gchar *plname,
                                   xmms_error_t *err)
{
	GList *entries = NULL;
	xmmsv_coll_t *plcoll;
	xmms_medialib_entry_t entry;
	xmmsv_list_iter_t *it;

	g_return_val_if_fail (playlist, NULL);

	g_mutex_lock (playlist->mutex);

	plcoll = xmms_playlist_get_coll (playlist, plname, err);
	if (plcoll == NULL) {
		g_mutex_unlock (playlist->mutex);
		return NULL;
	}

	xmmsv_get_list_iter (xmmsv_coll_idlist_get (plcoll), &it);
	for (xmmsv_list_iter_first (it);
	     xmmsv_list_iter_valid (it);
	     xmmsv_list_iter_next (it)) {

		xmmsv_list_iter_entry_int (it, &entry);
		entries = g_list_prepend (entries, xmmsv_new_int (entry));
	}
	xmmsv_list_iter_explicit_destroy (it);

	g_mutex_unlock (playlist->mutex);

	entries = g_list_reverse (entries);

	return entries;
}
Пример #4
0
static void
update_playtime (xmms_output_t *output, int advance)
{
	guint buffersize = 0;

	g_mutex_lock (&output->playtime_mutex);
	output->played += advance;
	g_mutex_unlock (&output->playtime_mutex);

	buffersize = xmms_output_plugin_method_latency_get (output->plugin, output);

	if (output->played < buffersize) {
		buffersize = output->played;
	}

	g_mutex_lock (&output->playtime_mutex);

	if (output->format) {
		guint ms = xmms_sample_bytes_to_ms (output->format,
		                                    output->played - buffersize);
		if ((ms / 100) != (output->played_time / 100)) {
			xmms_object_emit (XMMS_OBJECT (output),
			                  XMMS_IPC_SIGNAL_PLAYBACK_PLAYTIME,
			                  xmmsv_new_int (ms));
		}
		output->played_time = ms;

	}

	g_mutex_unlock (&output->playtime_mutex);

}
static xmmsv_t *
aggregate_set (xmmsv_t *current, gint int_value, const gchar *str_value)
{
	set_data_t *data;
	xmmsv_t *value;
	gpointer key;
	guint length;

	if (current == NULL) {
		set_data_t init = {
			.ht = g_hash_table_new (NULL, NULL),
			.list = xmmsv_new_list ()
		};
		current = xmmsv_new_bin ((guchar *) &init, sizeof (set_data_t));
	}

	xmmsv_get_bin (current, (const guchar **) &data, &length);

	if (str_value != NULL) {
		value = xmmsv_new_string (str_value);
		key = (gpointer) str_value;
	} else {
		value = xmmsv_new_int (int_value);
		key = GINT_TO_POINTER (int_value);
	}

	if (g_hash_table_lookup (data->ht, key) == NULL) {
		g_hash_table_insert (data->ht, key, value);
		xmmsv_list_append (data->list, value);
	}

	xmmsv_unref (value);

	return current;
}
Пример #6
0
/**
 * Trigger a removed siginal to the client. This should be
 * called when an entry has been removed from the medialib
 *
 * @param entry Entry to signal a remove for.
 */
static void
xmms_medialib_entry_send_removed (xmms_medialib_t *medialib, xmms_medialib_entry_t entry)
{
	xmms_object_emit (XMMS_OBJECT (medialib),
	                  XMMS_IPC_SIGNAL_MEDIALIB_ENTRY_REMOVED,
	                  xmmsv_new_int (entry));
}
static xmmsv_t *
aggregate_random (xmmsv_t *current, gint int_value, const gchar *str_value)
{
	random_data_t *data;
	guint length;

	if (current == NULL) {
		random_data_t init = { 0 };
		current = xmmsv_new_bin ((guchar *) &init, sizeof (random_data_t));
	}

	xmmsv_get_bin (current, (const guchar **) &data, &length);

	data->n++;

	if (g_random_int_range (0, data->n) == 0) {
		if (data->data != NULL) {
			xmmsv_unref (data->data);
		}

		if (str_value != NULL) {
			data->data = xmmsv_new_string (str_value);
		} else {
			data->data = xmmsv_new_int (int_value);
		}
	}

	return current;
}
Пример #8
0
static xmms_xspf_track_attr_t *
xmms_xspf_track_attr_from_node (const xmms_xspf_track_prop_t *prop, xmlNodePtr node)
{
	xmmsv_t *value;
	xmms_xspf_track_attr_t *attr;

	switch (prop->attr_type) {
		case XMMS_XSPF_TRACK_ATTR_TYPE_STRING:
			value = xmmsv_new_string ((char *)node->children->content);
			break;
		case XMMS_XSPF_TRACK_ATTR_TYPE_INT32: {
			/* TODO: check for errors */
			gint32 val = strtol ((char *)node->children->content, (char **)NULL, 10);
			value = xmmsv_new_int (val);
			break;
		}
	}

	if (!value) {
		return NULL;
	}

	attr = g_new0 (xmms_xspf_track_attr_t, 1);
	attr->key = prop->name;
	attr->value = value;

	return attr;
}
Пример #9
0
static void
xmms_medialib_entry_send_update (xmms_medialib_t *medialib, xmms_medialib_entry_t entry)
{
	xmms_object_emit (XMMS_OBJECT (medialib),
	                  XMMS_IPC_SIGNAL_MEDIALIB_ENTRY_UPDATE,
	                  xmmsv_new_int (entry));
}
Пример #10
0
gboolean
xmms_xform_metadata_set_int (xmms_xform_t *xform, const char *key, int val)
{
	g_hash_table_insert (xform->metadata, g_strdup (key),
	                     xmmsv_new_int (val));
	xform->metadata_changed = TRUE;
	return TRUE;
}
Пример #11
0
void
xmms_xform_metadata_set_int (xmms_xform_t *xform, const char *key, int val)
{
	XMMS_DBG ("Setting '%s' to %d", key, val);
	g_hash_table_insert (xform->metadata, g_strdup (key),
	                     xmmsv_new_int (val));
	xform->metadata_changed = TRUE;
}
Пример #12
0
void
xmms_xform_browse_add_entry_property_int (xmms_xform_t *xform,
                                          const gchar *key,
                                          gint value)
{
	xmmsv_t *val = xmmsv_new_int (value);
	xmms_xform_browse_add_entry_property (xform, key, val);
	xmmsv_unref (val);
}
Пример #13
0
static xmmsv_t *
create_data (int type, const char *data, uint32_t len)
{
	switch (type) {
		case JSON_STRING:
			return xmmsv_new_string (data);
		case JSON_INT:
			return xmmsv_new_int (atoi(data));
		case JSON_FLOAT:
			return xmmsv_new_float (strtof (data, NULL));
		case JSON_NULL:
			return xmmsv_new_none ();
		case JSON_TRUE:
			return xmmsv_new_int (1);
		case JSON_FALSE:
			return xmmsv_new_int (0);
		default:
			return xmmsv_new_error ("Unknown data type.");
	}
}
Пример #14
0
/* Converts an S4 resultset into an xmmsv_t, based on the fetch specification */
xmmsv_t *
xmms_medialib_query_to_xmmsv (s4_resultset_t *set, xmms_fetch_spec_t *spec)
{
	GHashTable *set_table;
	GList *sets;
	xmmsv_t *val, *ret = NULL;
	gint i;

	switch (spec->type) {
		case FETCH_COUNT:
			ret = xmmsv_new_int (s4_resultset_get_rowcount (set));
			break;
		case FETCH_METADATA:
			ret = metadata_to_xmmsv (set, spec);
			break;
		case FETCH_ORGANIZE:
			ret = xmmsv_new_dict ();

			for (i = 0; i < spec->data.organize.count; i++) {
				val = xmms_medialib_query_to_xmmsv (set, spec->data.organize.data[i]);
				if (val != NULL) {
					xmmsv_dict_set (ret, spec->data.organize.keys[i], val);
					xmmsv_unref (val);
				}
			}
			break;
		case FETCH_CLUSTER_LIST:
			sets = cluster_list (set, spec);
			ret = xmmsv_new_list ();
			for (; sets != NULL; sets = g_list_delete_link (sets, sets)) {
				set = sets->data;

				val = xmms_medialib_query_to_xmmsv (set, spec->data.cluster.data);
				if (val != NULL) {
					xmmsv_list_append (ret, val);
					xmmsv_unref (val);
				}
				s4_resultset_free (set);
			}
			break;
		case FETCH_CLUSTER_DICT:
			set_table = cluster_dict (set, spec);
			ret = convert_ghashtable_to_xmmsv (set_table, spec->data.cluster.data);

			g_hash_table_destroy (set_table);
			break;
		default:
			g_assert_not_reached ();
	}

	return ret;
}
Пример #15
0
/**
 * 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;
}
Пример #16
0
static xmmsv_t *
aggregate_max (xmmsv_t *current, gint int_value, const gchar *str_value)
{
	gint old_value;

	if (str_value != NULL) {
		/* 'max' only applies to numbers */
		return current;
	}

	if (current == NULL) {
		return xmmsv_new_int (int_value);
	}

	xmmsv_get_int (current, &old_value);

	if (old_value < int_value) {
		return xmmsv_new_int (int_value);
	}

	return current;
}
Пример #17
0
static gboolean
kill_server (gpointer object) {
	xmms_main_t *mainobj = (xmms_main_t *) object;
	gint uptime = time (NULL) - mainobj->starttime;

	xmms_object_emit (XMMS_OBJECT (object),
	                  XMMS_IPC_SIGNAL_QUIT,
	                  xmmsv_new_int (uptime));

	xmms_object_unref (object);

	exit (EXIT_SUCCESS);
}
Пример #18
0
static xmmsv_t *
aggregate_first (xmmsv_t *current, gint int_value, const gchar *str_value)
{
	if (current != NULL) {
		return current;
	}

	if (str_value != NULL) {
		current = xmmsv_new_string (str_value);
	} else {
		current = xmmsv_new_int (int_value);
	}

	return current;
}
Пример #19
0
static xmmsv_t *
aggregate_sum (xmmsv_t *current, gint int_value, const gchar *str_value)
{
	int64_t old_value = 0;

	if (str_value != NULL) {
		/* 'sum' only applies to numbers */
		return current;
	}

	if (current != NULL) {
		xmmsv_get_int64 (current, &old_value);
	}

	return xmmsv_new_int (old_value + int_value);
}
Пример #20
0
/**
 * This returns the main stats for the server
 */
static GTree *
xmms_main_client_stats (xmms_object_t *object, xmms_error_t *error)
{
	GTree *ret;
	gint starttime;

	ret = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
	                       NULL, (GDestroyNotify) xmmsv_unref);

	starttime = ((xmms_main_t*)object)->starttime;

	g_tree_insert (ret, (gpointer) "version",
	               xmmsv_new_string (XMMS_VERSION));
	g_tree_insert (ret, (gpointer) "uptime",
	               xmmsv_new_int (time (NULL) - starttime));

	return ret;
}
Пример #21
0
void
xmms_object_emit_f (xmms_object_t *object, guint32 signalid,
                    xmmsv_type_t type, ...)
{
	va_list ap;
	xmmsv_t *arg;

	va_start (ap, type);

	switch (type) {
		case XMMSV_TYPE_NONE:
			arg = xmmsv_new_none ();
			break;
		case XMMSV_TYPE_INT32:
			arg = xmmsv_new_int (va_arg (ap, gint32));
			break;
		case XMMSV_TYPE_STRING:
			arg = xmmsv_new_string (va_arg (ap, gchar *));
			break;
		case XMMSV_TYPE_DICT:
			arg = xmms_create_xmmsv_dict (va_arg (ap, GTree *));
			break;
		case XMMSV_TYPE_END:
		default:
			XMMS_DBG ("OBJECT: trying to emit value of unsupported type (%d)!", (int)type);
			g_assert_not_reached ();
			break;
	}
	va_end (ap);

	xmms_object_emit (object, signalid, arg);

	/* In all cases above, we created a new xmmsv_t, which we
	 * now destroy.
	 * In some cases, those xmmsv_t's are created from GLib objects,
	 * such as GTrees. Here we must not destroy those GLib objects,
	 * because the caller wants to do that. However, the xmmsv_t's
	 * don't hold onto those GLib objects, so unreffing the
	 * xmmsv_t doesn't kill the GLib object.
	 */
	xmmsv_unref (arg);
}
Пример #22
0
static gboolean
song_changed (void *data)
{
	/* executes in the output thread; NOT the filler thread */
	xmms_output_song_changed_arg_t *arg = (xmms_output_song_changed_arg_t *)data;
	xmms_medialib_entry_t entry;
	xmms_stream_type_t *type;

	entry = xmms_xform_entry_get (arg->chain);

	XMMS_DBG ("Running hotspot! Song changed!! %d", entry);

	arg->output->played = 0;
	arg->output->current_entry = entry;

	type = xmms_xform_outtype_get (arg->chain);

	if (!xmms_output_format_set (arg->output, type)) {
		gint fmt, rate, chn;

		fmt = xmms_stream_type_get_int (type, XMMS_STREAM_TYPE_FMT_FORMAT);
		rate = xmms_stream_type_get_int (type, XMMS_STREAM_TYPE_FMT_SAMPLERATE);
		chn = xmms_stream_type_get_int (type, XMMS_STREAM_TYPE_FMT_CHANNELS);

		XMMS_DBG ("Couldn't set format %s/%d/%d, stopping filler..",
		          xmms_sample_name_get (fmt), rate, chn);

		xmms_output_filler_state_nolock (arg->output, FILLER_STOP);
		xmms_ringbuf_set_eos (arg->output->filler_buffer, TRUE);
		return FALSE;
	}

	if (arg->flush)
		xmms_output_flush (arg->output);

	xmms_object_emit (XMMS_OBJECT (arg->output),
	                  XMMS_IPC_SIGNAL_PLAYBACK_CURRENTID,
	                  xmmsv_new_int (entry));

	return TRUE;
}
Пример #23
0
static GTree *
xmms_volume_map_to_dict (xmms_volume_map_t *vl)
{
	GTree *ret;
	gint i;

	ret = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
	                       NULL, (GDestroyNotify) xmmsv_unref);
	if (!ret) {
		return NULL;
	}

	for (i = 0; i < vl->num_channels; i++) {
		xmmsv_t *val;

		val = xmmsv_new_int (vl->values[i]);
		g_tree_replace (ret, (gpointer) vl->names[i], val);
	}

	return ret;
}
Пример #24
0
static gboolean
xmms_output_status_set (xmms_output_t *output, gint status)
{
	gboolean ret = TRUE;

	if (!output->plugin) {
		XMMS_DBG ("No plugin to set status on..");
		return FALSE;
	}

	g_mutex_lock (&output->status_mutex);

	if (output->status != status) {
		if (status == XMMS_PLAYBACK_STATUS_PAUSE &&
		    output->status != XMMS_PLAYBACK_STATUS_PLAY) {
			XMMS_DBG ("Can only pause from play.");
			ret = FALSE;
		} else {
			output->status = status;

			if (status == XMMS_PLAYBACK_STATUS_STOP) {
				xmms_object_unref (output->format);
				output->format = NULL;
			}
			if (!xmms_output_plugin_method_status (output->plugin, output, status)) {
				xmms_log_error ("Status method returned an error!");
				output->status = XMMS_PLAYBACK_STATUS_STOP;
				ret = FALSE;
			}

			xmms_object_emit (XMMS_OBJECT (output),
			                  XMMS_IPC_SIGNAL_PLAYBACK_STATUS,
			                  xmmsv_new_int (output->status));
		}
	}

	g_mutex_unlock (&output->status_mutex);

	return ret;
}
Пример #25
0
xmmsv_t *
xmms_medialib_entry_property_get_value (xmms_medialib_session_t *session,
                                        xmms_medialib_entry_t id_num,
                                        const gchar *property)
{
	xmmsv_t *ret = NULL;
	s4_val_t *prop;
	const gchar *s;
	gint32 i;

	prop = xmms_medialib_entry_property_get (session, id_num, property);
	if (prop == NULL)
		return NULL;

	if (s4_val_get_str (prop, &s)) {
		ret = xmmsv_new_string (s);
	} else if (s4_val_get_int (prop, &i)) {
		ret = xmmsv_new_int (i);
	}

	s4_val_free (prop);

	return ret;
}
Пример #26
0
static void
__int_xmms_cmd_get_id (xmms_object_t *object, xmms_object_cmd_arg_t *arg)
{
	xmmsv_t *t;
	if (xmmsv_list_get_size (arg->args) != 1) {
		XMMS_DBG ("Wrong number of arguments to get_id (%d)", xmmsv_list_get_size (arg->args));
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to get_id");
		return;
	}
	const char * argval0;

	if (!xmmsv_list_get (arg->args, 0, &t)) {
		XMMS_DBG ("Missing arg 0 in get_id");
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in get_id");
		return;
	}
	if (!xmmsv_get_string (t, &argval0)) {
		XMMS_DBG ("Error parsing arg 0 in get_id");
		xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in get_id");
		return;
	}

	arg->retval = xmmsv_new_int (xmms_medialib_client_get_id ((xmms_medialib_t *) object, argval0, &arg->error));
}
Пример #27
0
static bool
_internal_get_from_bb_value_of_type_alloc (xmmsv_t *bb, xmmsv_type_t type,
                                           xmmsv_t **val)
{
	int32_t i;
	uint32_t len;
	char *s;
	xmmsv_coll_t *c;
	unsigned char *d;

	switch (type) {
		case XMMSV_TYPE_ERROR:
			if (!_internal_get_from_bb_error_alloc (bb, &s, &len)) {
				return false;
			}
			*val = xmmsv_new_error (s);
			free (s);
			break;
		case XMMSV_TYPE_INT32:
			if (!_internal_get_from_bb_int32 (bb, &i)) {
				return false;
			}
			*val = xmmsv_new_int (i);
			break;
		case XMMSV_TYPE_STRING:
			if (!_internal_get_from_bb_string_alloc (bb, &s, &len)) {
				return false;
			}
			*val = xmmsv_new_string (s);
			free (s);
			break;
		case XMMSV_TYPE_DICT:
			if (!xmmsc_deserialize_dict (bb, val)) {
				return false;
			}
			break;

		case XMMSV_TYPE_LIST :
			if (!xmmsc_deserialize_list (bb, val)) {
				return false;
			}
			break;

		case XMMSV_TYPE_COLL:
			if (!_internal_get_from_bb_collection_alloc (bb, &c)) {
				return false;
			}
			*val = xmmsv_new_coll (c);
			xmmsv_coll_unref (c);
			break;

		case XMMSV_TYPE_BIN:
			if (!_internal_get_from_bb_bin_alloc (bb, &d, &len)) {
				return false;
			}
			*val = xmmsv_new_bin (d, len);
			free (d);
			break;

		case XMMSV_TYPE_NONE:
			*val = xmmsv_new_none ();
			break;
		default:
			x_internal_error ("Got message of unknown type!");
			return false;
	}

	return true;
}
Пример #28
0
void
xmms_xform_auxdata_set_int (xmms_xform_t *xform, const char *key, int intval)
{
	xmmsv_t *val = xmmsv_new_int (intval);
	xmms_xform_auxdata_set_val (xform, g_strdup (key), val);
}