示例#1
0
文件: playlist.c 项目: dsheeler/xmms2
static void
xmms_playlist_destroy (xmms_object_t *object)
{
	xmms_config_property_t *val;
	xmms_playlist_t *playlist = (xmms_playlist_t *) object;

	XMMS_DBG ("Deactivating playlist object");

	g_return_if_fail (playlist);

	val = xmms_config_lookup ("playlist.repeat_one");
	xmms_config_property_callback_remove (val, on_playlist_r_one_changed, playlist);

	val = xmms_config_lookup ("playlist.repeat_all");
	xmms_config_property_callback_remove (val, on_playlist_r_all_changed, playlist);

	xmms_object_disconnect (XMMS_OBJECT (playlist->medialib),
	                        XMMS_IPC_SIGNAL_MEDIALIB_ENTRY_REMOVED,
	                        on_medialib_entry_removed, playlist);

	xmms_object_disconnect (XMMS_OBJECT (playlist->colldag),
	                        XMMS_IPC_SIGNAL_COLLECTION_CHANGED,
	                        on_collection_changed, playlist);

	xmms_object_unref (playlist->colldag);
	xmms_object_unref (playlist->medialib);

	g_mutex_free (playlist->mutex);

	xmms_playlist_unregister_ipc_commands ();
}
示例#2
0
xmms_playlist_updater_t *
xmms_playlist_updater_init (xmms_playlist_t *playlist)
{
	xmms_playlist_updater_t *updater;

	updater = xmms_object_new (xmms_playlist_updater_t,
	                           xmms_playlist_updater_destroy);

	updater->cond = g_cond_new ();
	updater->mutex = g_mutex_new ();

	xmms_object_ref (playlist);
	updater->playlist = playlist;

	updater->updating = NULL;
	updater->stack = NULL;

	xmms_object_connect (XMMS_OBJECT (playlist),
	                     XMMS_IPC_SIGNAL_COLLECTION_CHANGED,
	                     xmms_playlist_updater_need_update, updater);

	xmms_object_connect (XMMS_OBJECT (playlist),
	                     XMMS_IPC_SIGNAL_PLAYLIST_CHANGED,
	                     xmms_playlist_updater_need_update, updater);

	xmms_object_connect (XMMS_OBJECT (playlist),
	                     XMMS_IPC_SIGNAL_PLAYLIST_CURRENT_POS,
	                     xmms_playlist_updater_need_update, updater);

	xmms_playlist_updater_start (updater);

	return updater;
}
示例#3
0
文件: playlist.c 项目: dsheeler/xmms2
/**
 * Initializes a new xmms_playlist_t.
 */
xmms_playlist_t *
xmms_playlist_init (xmms_medialib_t *medialib, xmms_coll_dag_t *colldag)
{
	xmms_playlist_t *ret;
	xmms_config_property_t *val;

	ret = xmms_object_new (xmms_playlist_t, xmms_playlist_destroy);
	ret->mutex = g_mutex_new ();

	xmms_playlist_register_ipc_commands (XMMS_OBJECT (ret));

	val = xmms_config_property_register ("playlist.repeat_one", "0",
	                                     on_playlist_r_one_changed, ret);
	ret->repeat_one = xmms_config_property_get_int (val);

	val = xmms_config_property_register ("playlist.repeat_all", "0",
	                                  on_playlist_r_all_changed, ret);
	ret->repeat_all = xmms_config_property_get_int (val);

	xmms_object_ref (medialib);
	ret->medialib = medialib;

	xmms_object_ref (colldag);
	ret->colldag = colldag;

	xmms_object_connect (XMMS_OBJECT (ret->medialib),
	                     XMMS_IPC_SIGNAL_MEDIALIB_ENTRY_REMOVED,
	                     on_medialib_entry_removed, ret);

	xmms_object_connect (XMMS_OBJECT (ret->colldag),
	                     XMMS_IPC_SIGNAL_COLLECTION_CHANGED,
	                     on_collection_changed, ret);

	return ret;
}
示例#4
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));
}
示例#5
0
xmms_medialib_t *
xmms_medialib_init (void)
{
	xmms_config_property_t *cfg;
	xmms_medialib_t *medialib;
	const gchar *medialib_path;
	gchar *path;

	const gchar *indices[] = {
		XMMS_MEDIALIB_ENTRY_PROPERTY_URL,
		XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS,
		NULL
	};

	medialib = xmms_object_new (xmms_medialib_t, xmms_medialib_destroy);

	xmms_medialib_register_ipc_commands (XMMS_OBJECT (medialib));

	path = XMMS_BUILD_PATH ("medialib.s4");
	cfg = xmms_config_property_register ("medialib.path", path, NULL, NULL);
	g_free (path);

	path = XMMS_BUILD_PATH ("collections", "${uuid}");
	xmms_config_property_register ("collection.directory", path, NULL, NULL);
	g_free (path);

	xmms_config_property_register ("sqlite2s4.path", "sqlite2s4", NULL, NULL);

	medialib_path = xmms_config_property_get_string (cfg);
	medialib->s4 = xmms_medialib_database_open (medialib_path, indices);
	medialib->default_sp = s4_sourcepref_create (xmmsv_default_source_pref);

	return medialib;
}
示例#6
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;

	entry = xmms_xform_entry_get (arg->chain);

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

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

	if (!xmms_output_format_set (arg->output, xmms_xform_outtype_get (arg->chain))) {
		XMMS_DBG ("Couldn't set format, stopping filler..");
		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_f (XMMS_OBJECT (arg->output),
	                    XMMS_IPC_SIGNAL_OUTPUT_CURRENTID,
	                    XMMSV_TYPE_UINT32,
	                    entry);

	return TRUE;
}
示例#7
0
文件: main.c 项目: dreamerc/xmms2
/**
 * @internal Destroy the main object
 * @param[in] object The object to destroy
 */
static void
xmms_main_destroy (xmms_object_t *object)
{
	xmms_main_t *mainobj = (xmms_main_t *) object;
	xmms_object_cmd_arg_t arg;
	xmms_config_property_t *cv;

	cv = xmms_config_lookup ("core.shutdownpath");
	do_scriptdir (xmms_config_property_get_string (cv), "stop");

	/* stop output */
	xmms_object_cmd_arg_init (&arg);

	xmms_object_cmd_call (XMMS_OBJECT (mainobj->output),
	                      XMMS_IPC_CMD_STOP, &arg);

	g_usleep (G_USEC_PER_SEC); /* wait for the output thread to end */

	xmms_object_unref (mainobj->vis);
	xmms_object_unref (mainobj->output);

	xmms_object_unref (xform_obj);

	xmms_config_save ();

	xmms_config_shutdown ();

	xmms_plugin_shutdown ();

	xmms_ipc_object_unregister (XMMS_IPC_OBJECT_MAIN);
	xmms_ipc_shutdown ();

	xmms_log_shutdown ();
}
示例#8
0
文件: playlist.c 项目: dsheeler/xmms2
static void
xmms_playlist_client_load (xmms_playlist_t *playlist, const gchar *name, xmms_error_t *err)
{
	xmmsv_coll_t *plcoll, *active_coll;

	if (strcmp (name, XMMS_ACTIVE_PLAYLIST) == 0) {
		xmms_error_set (err, XMMS_ERROR_INVAL, "invalid playlist to load");
		return;
	}

	active_coll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err);
	if (active_coll == NULL) {
		xmms_error_set (err, XMMS_ERROR_GENERIC, "no active playlist");
		return;
	}

	plcoll = xmms_playlist_get_coll (playlist, name, err);
	if (plcoll == NULL) {
		xmms_error_set (err, XMMS_ERROR_NOENT, "no such playlist");
		return;
	}

	if (active_coll == plcoll) {
		XMMS_DBG ("Not loading %s playlist, already active!", name);
		return;
	}

	XMMS_DBG ("Loading new playlist! %s", name);
	xmms_collection_update_pointer (playlist->colldag, XMMS_ACTIVE_PLAYLIST,
	                                XMMS_COLLECTION_NSID_PLAYLISTS, plcoll);

	xmms_object_emit (XMMS_OBJECT (playlist),
	                  XMMS_IPC_SIGNAL_PLAYLIST_LOADED,
	                  xmmsv_new_string (name));
}
示例#9
0
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_f (XMMS_OBJECT (output),
			                    XMMS_IPC_SIGNAL_OUTPUT_PLAYTIME,
			                    XMMSV_TYPE_UINT32,
			                    ms);
		}
		output->played_time = ms;

	}

	g_mutex_unlock (output->playtime_mutex);

}
示例#10
0
static gboolean
xmms_normalize_init (xmms_xform_t *xform)
{
	xmms_config_property_t *cfgv;
	xmms_normalize_data_t *data;
	int i;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_normalize_data_t, 1);

	for (i = 0; i < G_N_ELEMENTS (config_params); i++) {
		cfgv = xmms_xform_config_lookup (xform, config_params[i].key);
		xmms_config_property_callback_set (cfgv,
		                                   xmms_normalize_config_changed,
		                                   data);

		xmms_normalize_config_changed (XMMS_OBJECT (cfgv), NULL, data);
	}

	xmms_xform_outdata_type_copy (xform);

	data->dirty = FALSE;

	data->compress = compress_new (data->use_anticlip,
	                               data->target,
	                               data->max_gain,
	                               data->smooth,
	                               data->buckets);

	xmms_xform_private_data_set (xform, data);

	return TRUE;
}
示例#11
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));
}
示例#12
0
文件: main.c 项目: dreamerc/xmms2
static gboolean
kill_server (gpointer object) {
	xmms_object_emit_f (XMMS_OBJECT (object),
	                    XMMS_IPC_SIGNAL_QUIT,
	                    XMMSV_TYPE_INT32,
	                    time (NULL)-((xmms_main_t*)object)->starttime);

	xmms_object_unref (object);

	exit (EXIT_SUCCESS);
}
示例#13
0
文件: playlist.c 项目: dsheeler/xmms2
static void
xmms_playlist_current_pos_msg_send (xmms_playlist_t *playlist,
                                    xmmsv_t *dict)
{
	g_return_if_fail (playlist);
	g_return_if_fail (dict);

	xmms_object_emit (XMMS_OBJECT (playlist),
	                  XMMS_IPC_SIGNAL_PLAYLIST_CURRENT_POS,
	                  dict);
}
示例#14
0
gpointer
xmms_object_ref (gpointer obj)
{
	xmms_object_t *object;

	g_return_val_if_fail (obj && XMMS_IS_OBJECT (obj), obj);

	object = XMMS_OBJECT (obj);
	g_atomic_int_inc (&(object->ref));

	return obj;
}
示例#15
0
xmms_xform_object_t *
xmms_xform_object_init (void)
{
	xmms_xform_object_t *obj;

	obj = xmms_object_new (xmms_xform_object_t, xmms_xform_object_destroy);

	xmms_xform_register_ipc_commands (XMMS_OBJECT (obj));

	effect_callbacks_init ();

	return obj;
}
示例#16
0
文件: main.c 项目: chrippa/xmms2
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);
}
示例#17
0
xmms_mediainfo_reader_t *
xmms_mediainfo_reader_start (void)
{
	xmms_mediainfo_reader_t *mrt;

	mrt = xmms_object_new (xmms_mediainfo_reader_t,
	                       xmms_mediainfo_reader_stop);

	xmms_ipc_object_register (XMMS_IPC_OBJECT_MEDIAINFO_READER,
	                          XMMS_OBJECT (mrt));

	xmms_ipc_broadcast_register (XMMS_OBJECT (mrt),
	                             XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS);
	xmms_ipc_signal_register (XMMS_OBJECT (mrt),
	                          XMMS_IPC_SIGNAL_MEDIAINFO_READER_UNINDEXED);

	mrt->mutex = g_mutex_new ();
	mrt->cond = g_cond_new ();
	mrt->running = TRUE;
	mrt->thread = g_thread_create (xmms_mediainfo_reader_thread, mrt, TRUE, NULL);

	return mrt;
}
示例#18
0
/**
 * Allocate a new #xmms_output_t
 */
xmms_output_t *
xmms_output_new (xmms_output_plugin_t *plugin, xmms_playlist_t *playlist, xmms_medialib_t *medialib)
{
	xmms_output_t *output;
	xmms_config_property_t *prop;
	gint size;

	g_return_val_if_fail (playlist, NULL);

	XMMS_DBG ("Trying to open output");

	output = xmms_object_new (xmms_output_t, xmms_output_destroy);

	xmms_object_ref (playlist);
	output->playlist = playlist;

	xmms_object_ref (medialib);
	output->medialib = medialib;

	g_mutex_init (&output->status_mutex);
	g_mutex_init (&output->playtime_mutex);

	prop = xmms_config_property_register ("output.buffersize", "32768", NULL, NULL);
	size = xmms_config_property_get_int (prop);
	XMMS_DBG ("Using buffersize %d", size);

	g_mutex_init (&output->filler_mutex);
	output->filler_state = FILLER_STOP;
	g_cond_init (&output->filler_state_cond);
	output->filler_buffer = xmms_ringbuf_new (size);
	output->filler_thread = g_thread_new ("x2 out filler", xmms_output_filler, output);

	xmms_config_property_register ("output.flush_on_pause", "1", NULL, NULL);

	xmms_playback_register_ipc_commands (XMMS_OBJECT (output));

	output->status = XMMS_PLAYBACK_STATUS_STOP;

	if (plugin) {
		if (!set_plugin (output, plugin)) {
			xmms_log_error ("Could not initialize output plugin");
		}
	} else {
		xmms_log_error ("initalized output without a plugin, please fix!");
	}



	return output;
}
示例#19
0
static void
xmms_playlist_updater_destroy (xmms_object_t *object)
{
	GList *it;
	xmms_playlist_updater_t *updater = (xmms_playlist_updater_t *) object;

	g_return_if_fail (updater != NULL);

	XMMS_DBG ("Deactivating playlist updater object.");

	xmms_object_disconnect (XMMS_OBJECT (updater->playlist),
	                        XMMS_IPC_SIGNAL_COLLECTION_CHANGED,
	                        xmms_playlist_updater_need_update, updater);

	xmms_object_disconnect (XMMS_OBJECT (updater->playlist),
	                        XMMS_IPC_SIGNAL_PLAYLIST_CHANGED,
	                        xmms_playlist_updater_need_update, updater);

	xmms_object_disconnect (XMMS_OBJECT (updater->playlist),
	                        XMMS_IPC_SIGNAL_PLAYLIST_CURRENT_POS,
	                        xmms_playlist_updater_need_update, updater);

	xmms_playlist_updater_stop (updater);

	xmms_object_unref (updater->playlist);

	for (it = updater->stack; it; it = g_list_next (it)) {
		gchar *plname;
		plname = (gchar *) it->data;
		g_free (plname);
	}
	g_list_free (updater->stack);

	g_mutex_free (updater->mutex);
	g_cond_free (updater->cond);
}
示例#20
0
/**
 * Initialize the Vis module.
 */
xmms_visualization_t *
xmms_visualization_new (xmms_output_t *output)
{
	vis = xmms_object_new (xmms_visualization_t, xmms_visualization_destroy);
	g_mutex_init (&vis->clientlock);
	vis->clientc = 0;
	vis->output = output;

	xmms_object_ref (output);

	xmms_visualization_register_ipc_commands (XMMS_OBJECT (vis));

	xmms_socket_invalidate (&vis->socket);

	return vis;
}
示例#21
0
void
xmms_object_unref (gpointer obj)
{
	xmms_object_t *object;

	g_return_if_fail (obj && XMMS_IS_OBJECT (obj));

	object = XMMS_OBJECT (obj);
	g_return_if_fail (object->ref > 0);

	if (g_atomic_int_dec_and_test (&(object->ref))) {
		if (object->destroy_func)
			object->destroy_func (object);
		xmms_object_cleanup (object);
		g_free (object);
	}
}
示例#22
0
文件: playlist.c 项目: dsheeler/xmms2
void
xmms_playlist_changed_msg_send (xmms_playlist_t *playlist, xmmsv_t *dict)
{
	const gchar *plname;
	gint type;

	g_return_if_fail (playlist);
	g_return_if_fail (dict);

	/* If local playlist change, trigger a COLL_CHANGED signal */
	if (xmmsv_dict_entry_get_int (dict, "type", &type) &&
	    xmmsv_dict_entry_get_string (dict, "name", &plname) &&
	    type != XMMS_PLAYLIST_CHANGED_UPDATE) {
		XMMS_COLLECTION_PLAYLIST_CHANGED_MSG (playlist->colldag, plname);
	}

	xmms_object_emit (XMMS_OBJECT (playlist),
	                  XMMS_IPC_SIGNAL_PLAYLIST_CHANGED,
	                  dict);
}
示例#23
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_f (XMMS_OBJECT (output),
			                    XMMS_IPC_SIGNAL_PLAYBACK_STATUS,
			                    XMMSV_TYPE_UINT32,
			                    output->status);
		}
	}

	g_mutex_unlock (output->status_mutex);

	return ret;
}
示例#24
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;
}
示例#25
0
/**
 * Allocate a new #xmms_output_t
 */
xmms_output_t *
xmms_output_new (xmms_output_plugin_t *plugin, xmms_playlist_t *playlist)
{
	xmms_output_t *output;
	xmms_config_property_t *prop;
	gint size;

	g_return_val_if_fail (playlist, NULL);

	XMMS_DBG ("Trying to open output");

	output = xmms_object_new (xmms_output_t, xmms_output_destroy);

	output->playlist = playlist;

	output->status_mutex = g_mutex_new ();
	output->playtime_mutex = g_mutex_new ();

	prop = xmms_config_property_register ("output.buffersize", "32768", NULL, NULL);
	size = xmms_config_property_get_int (prop);
	XMMS_DBG ("Using buffersize %d", size);

	output->filler_mutex = g_mutex_new ();
	output->filler_state = FILLER_STOP;
	output->filler_state_cond = g_cond_new ();
	output->filler_buffer = xmms_ringbuf_new (size);
	output->filler_thread = g_thread_create (xmms_output_filler, output, TRUE, NULL);

	xmms_config_property_register ("output.flush_on_pause", "1", NULL, NULL);
	xmms_ipc_object_register (XMMS_IPC_OBJECT_OUTPUT, XMMS_OBJECT (output));

	/* Broadcasts are always transmitted to the client if he
	 * listens to them. */
	xmms_ipc_broadcast_register (XMMS_OBJECT (output),
	                             XMMS_IPC_SIGNAL_OUTPUT_VOLUME_CHANGED);
	xmms_ipc_broadcast_register (XMMS_OBJECT (output),
	                             XMMS_IPC_SIGNAL_PLAYBACK_STATUS);
	xmms_ipc_broadcast_register (XMMS_OBJECT (output),
	                             XMMS_IPC_SIGNAL_OUTPUT_CURRENTID);

	/* Signals are only emitted if the client has a pending question to it
	 * after the client recivies a signal, he must ask for it again */
	xmms_ipc_signal_register (XMMS_OBJECT (output),
	                          XMMS_IPC_SIGNAL_OUTPUT_PLAYTIME);


	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_START,
	                     XMMS_CMD_FUNC (start));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_STOP,
	                     XMMS_CMD_FUNC (stop));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_PAUSE,
	                     XMMS_CMD_FUNC (pause));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_DECODER_KILL,
	                     XMMS_CMD_FUNC (xform_kill));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_CPLAYTIME,
	                     XMMS_CMD_FUNC (playtime));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_SEEKMS,
	                     XMMS_CMD_FUNC (seekms));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_SEEKMS_REL,
	                     XMMS_CMD_FUNC (seekms_rel));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_SEEKSAMPLES,
	                     XMMS_CMD_FUNC (seeksamples));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_SEEKSAMPLES_REL,
	                     XMMS_CMD_FUNC (seeksamples_rel));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_OUTPUT_STATUS,
	                     XMMS_CMD_FUNC (output_status));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_CURRENTID,
	                     XMMS_CMD_FUNC (currentid));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_VOLUME_SET,
	                     XMMS_CMD_FUNC (volume_set));
	xmms_object_cmd_add (XMMS_OBJECT (output),
	                     XMMS_IPC_CMD_VOLUME_GET,
	                     XMMS_CMD_FUNC (volume_get));

	output->status = XMMS_PLAYBACK_STATUS_STOP;

	if (plugin) {
		if (!set_plugin (output, plugin)) {
			xmms_log_error ("Could not initialize output plugin");
		}
	} else {
		xmms_log_error ("initalized output without a plugin, please fix!");
	}



	return output;
}
示例#26
0
文件: modplug.c 项目: theefer/xmms2
static gboolean
xmms_modplug_init (xmms_xform_t *xform)
{
	xmms_modplug_data_t *data;
	const gchar *metakey;
	gint filesize;
	xmms_config_property_t *cfgv;
	gint i;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_modplug_data_t, 1);

	xmms_xform_private_data_set (xform, data);

	for (i = 0; i < G_N_ELEMENTS (config_params); i++) {
		cfgv = xmms_xform_config_lookup (xform, config_params[i].key);
		xmms_config_property_callback_set (cfgv,
		                                   xmms_modplug_config_changed,
		                                   data);

		xmms_modplug_config_changed (XMMS_OBJECT (cfgv), NULL, data);
	}

	/* mFrequency and mResamplingMode are set in config_changed */
	data->settings.mChannels = 2;
	data->settings.mBits = 16;
	ModPlug_SetSettings (&data->settings);

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             XMMS_SAMPLE_FORMAT_S16,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             2,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             data->settings.mFrequency,
	                             XMMS_STREAM_TYPE_END);

	data->buffer = g_string_new ("");

	for (;;) {
		xmms_error_t error;
		gchar buf[4096];
		gint ret;

		ret = xmms_xform_read (xform, buf, sizeof (buf), &error);
		if (ret == -1) {
			XMMS_DBG ("Error reading mod");
			return FALSE;
		}
		if (ret == 0) {
			break;
		}
		g_string_append_len (data->buffer, buf, ret);
	}

	data->mod = ModPlug_Load (data->buffer->str, data->buffer->len);
	if (!data->mod) {
		XMMS_DBG ("Error loading mod");
		return FALSE;
	}

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE;
	if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION;
		xmms_xform_metadata_set_int (xform, metakey,
		                             ModPlug_GetLength (data->mod));
	}

	metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE;
	xmms_xform_metadata_set_str (xform, metakey, ModPlug_GetName (data->mod));

	return TRUE;
}
示例#27
0
static gpointer
xmms_output_monitor_volume_thread (gpointer data)
{
	GTree *dict;
	xmms_output_t *output = data;
	xmms_volume_map_t old, cur;

	if (!xmms_output_plugin_method_volume_get_available (output->plugin)) {
		return NULL;
	}

	xmms_volume_map_init (&old);
	xmms_volume_map_init (&cur);

	while (output->monitor_volume_running) {
		cur.num_channels = 0;
		cur.status = xmms_output_plugin_method_volume_get (output->plugin,
		                                                   output, NULL, NULL,
		                                                   &cur.num_channels);

		if (cur.status) {
			/* check for sane values */
			if (cur.num_channels < 1 ||
			    cur.num_channels > VOLUME_MAX_CHANNELS) {
				cur.status = FALSE;
			} else {
				cur.names = g_renew (const gchar *, cur.names,
				                     cur.num_channels);
				cur.values = g_renew (guint, cur.values, cur.num_channels);
			}
		}

		if (cur.status) {
			cur.status =
				xmms_output_plugin_method_volume_get (output->plugin,
				                                      output, cur.names,
				                                      cur.values,
				                                      &cur.num_channels);
		}

		/* we failed at getting volume for one of the two maps or
		 * we succeeded both times and they differ -> changed
		 */
		if ((cur.status ^ old.status) ||
		    (cur.status && old.status &&
		     !xmms_volume_map_equal (&old, &cur))) {
			/* emit the broadcast */
			if (cur.status) {
				dict = xmms_volume_map_to_dict (&cur);
				xmms_object_emit_f (XMMS_OBJECT (output),
				                    XMMS_IPC_SIGNAL_OUTPUT_VOLUME_CHANGED,
				                    XMMSV_TYPE_DICT, dict);
				g_tree_destroy (dict);
			} else {
				/** @todo When bug 691 is solved, emit an error here */
				xmms_object_emit_f (XMMS_OBJECT (output),
				                    XMMS_IPC_SIGNAL_OUTPUT_VOLUME_CHANGED,
				                    XMMSV_TYPE_NONE);
			}
		}

		xmms_volume_map_copy (&cur, &old);

		g_usleep (G_USEC_PER_SEC);
	}

	xmms_volume_map_free (&old);
	xmms_volume_map_free (&cur);

	return NULL;
}
示例#28
0
static gpointer
xmms_mediainfo_reader_thread (gpointer data)
{
	GList *goal_format;
	GTimeVal timeval;
	xmms_stream_type_t *f;
	guint num = 0;

	xmms_mediainfo_reader_t *mrt = (xmms_mediainfo_reader_t *) data;

	xmms_object_emit_f (XMMS_OBJECT (mrt),
	                    XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS,
	                    XMMSV_TYPE_INT32,
	                    XMMS_MEDIAINFO_READER_STATUS_RUNNING);


	f = _xmms_stream_type_new (NULL,
	                           XMMS_STREAM_TYPE_MIMETYPE,
	                           "audio/pcm",
	                           XMMS_STREAM_TYPE_END);
	goal_format = g_list_prepend (NULL, f);

	while (mrt->running) {
		xmms_medialib_session_t *session;
		xmmsc_medialib_entry_status_t prev_status;
		guint lmod = 0;
		xmms_medialib_entry_t entry;
		xmms_xform_t *xform;

		session = xmms_medialib_begin_write ();
		entry = xmms_medialib_entry_not_resolved_get (session);
		XMMS_DBG ("got %d as not resolved", entry);

		if (!entry) {
			xmms_medialib_end (session);

			xmms_object_emit_f (XMMS_OBJECT (mrt),
			                    XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS,
			                    XMMSV_TYPE_INT32,
			                    XMMS_MEDIAINFO_READER_STATUS_IDLE);

			g_mutex_lock (mrt->mutex);
			g_cond_wait (mrt->cond, mrt->mutex);
			g_mutex_unlock (mrt->mutex);

			num = 0;

			xmms_object_emit_f (XMMS_OBJECT (mrt),
			                    XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS,
			                    XMMSV_TYPE_INT32,
			                    XMMS_MEDIAINFO_READER_STATUS_RUNNING);
			continue;
		}

		prev_status = xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS);
		xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_RESOLVING);

		lmod = xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_LMOD);

		if (num == 0) {
			xmms_object_emit_f (XMMS_OBJECT (mrt),
			                    XMMS_IPC_SIGNAL_MEDIAINFO_READER_UNINDEXED,
			                    XMMSV_TYPE_INT32,
			                    xmms_medialib_num_not_resolved (session));
			num = 10;
		} else {
			num--;
		}

		xmms_medialib_end (session);
		xform = xmms_xform_chain_setup (entry, goal_format, TRUE);

		if (!xform) {
			if (prev_status == XMMS_MEDIALIB_ENTRY_STATUS_NEW) {
				xmms_medialib_entry_remove (entry);
			} else {
				session = xmms_medialib_begin_write ();
				xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE);
				xmms_medialib_end (session);
				xmms_medialib_entry_send_update (entry);
			}
			continue;
		}

		xmms_object_unref (xform);
		g_get_current_time (&timeval);

		session = xmms_medialib_begin_write ();
		xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_OK);
		xmms_medialib_entry_property_set_int (session, entry,
		                                      XMMS_MEDIALIB_ENTRY_PROPERTY_ADDED,
		                                      timeval.tv_sec);
		xmms_medialib_end (session);
		xmms_medialib_entry_send_update (entry);

	}

	g_list_free (goal_format);
	xmms_object_unref (f);

	return NULL;
}
示例#29
0
文件: main.c 项目: dreamerc/xmms2
/**
 * The xmms2 daemon main initialisation function
 */
int
main (int argc, char **argv)
{
	xmms_output_plugin_t *o_plugin;
	xmms_config_property_t *cv;
	xmms_main_t *mainobj;
	int loglevel = 1;
	xmms_playlist_t *playlist;
	gchar default_path[XMMS_PATH_MAX + 16], *tmp;
	gboolean verbose = FALSE;
	gboolean quiet = FALSE;
	gboolean version = FALSE;
	gboolean nologging = FALSE;
	gboolean runasroot = FALSE;
	gboolean showhelp = FALSE;
	const gchar *outname = NULL;
	const gchar *ipcpath = NULL;
	gchar *ppath = NULL;
	int status_fd = -1;
	GOptionContext *context = NULL;
	GError *error = NULL;

	setlocale (LC_ALL, "");

	/**
	 * The options that the server accepts.
	 */
	GOptionEntry opts[] = {
		{"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Increase verbosity", NULL},
		{"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Decrease verbosity", NULL},
		{"version", 'V', 0, G_OPTION_ARG_NONE, &version, "Print version", NULL},
		{"no-logging", 'n', 0, G_OPTION_ARG_NONE, &nologging, "Disable logging", NULL},
		{"output", 'o', 0, G_OPTION_ARG_STRING, &outname, "Use 'x' as output plugin", "<x>"},
		{"ipc-socket", 'i', 0, G_OPTION_ARG_FILENAME, &ipcpath, "Listen to socket 'url'", "<url>"},
		{"plugindir", 'p', 0, G_OPTION_ARG_FILENAME, &ppath, "Search for plugins in directory 'foo'", "<foo>"},
		{"conf", 'c', 0, G_OPTION_ARG_FILENAME, &conffile, "Specify alternate configuration file", "<file>"},
		{"status-fd", 's', 0, G_OPTION_ARG_INT, &status_fd, "Specify a filedescriptor to write to when started", "fd"},
		{"yes-run-as-root", 0, 0, G_OPTION_ARG_NONE, &runasroot, "Give me enough rope to shoot myself in the foot", NULL},
		{"show-help", 'h', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &showhelp, "Use --help or -? instead", NULL},
		{NULL}
	};

	/** Check that we are running against the correct glib version */
	if (glib_major_version != GLIB_MAJOR_VERSION ||
	    glib_minor_version < GLIB_MINOR_VERSION) {
		g_print ("xmms2d is build against version %d.%d,\n"
		         "but is (runtime) linked against %d.%d.\n"
		         "Refusing to start.\n",
		         GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
		         glib_major_version, glib_minor_version);
		exit (EXIT_FAILURE);
	}

	xmms_signal_block ();

	context = g_option_context_new ("- XMMS2 Daemon");
	g_option_context_add_main_entries (context, opts, NULL);
	if (!g_option_context_parse (context, &argc, &argv, &error) || error) {
		g_print ("Error parsing options: %s\n", error->message);
		g_clear_error (&error);
		exit (EXIT_FAILURE);
	}
	if (showhelp) {
#if GLIB_CHECK_VERSION(2,14,0)
		g_print ("%s", g_option_context_get_help (context, TRUE, NULL));
		exit (EXIT_SUCCESS);
#else
		g_print ("Please use --help or -? for help\n");
		exit (EXIT_FAILURE);
#endif
	}
	g_option_context_free (context);

	if (argc != 1) {
		g_print ("There were unknown options, aborting!\n");
		exit (EXIT_FAILURE);
	}

	if (xmms_checkroot ()) {
		if (runasroot) {
			g_print ("***************************************\n");
			g_print ("Warning! You are running XMMS2D as root, this is a bad idea!\nBut I'll allow it since you asked nicely.\n");
			g_print ("***************************************\n\n");
		} else {
			g_print ("PLEASE DON'T RUN XMMS2D AS ROOT!\n\n(if you really must, read the help)\n");
			exit (EXIT_FAILURE);
		}
	}

	if (verbose) {
		loglevel++;
	} else if (quiet) {
		loglevel--;
	}

	if (version) {
		print_version ();
	}

	g_thread_init (NULL);

	g_random_set_seed (time (NULL));

	xmms_log_init (loglevel);
	xmms_ipc_init ();

	load_config ();

	cv = xmms_config_property_register ("core.logtsfmt",
	                                    "%H:%M:%S ",
	                                    NULL, NULL);

	xmms_log_set_format (xmms_config_property_get_string (cv));

	xmms_fallback_ipcpath_get (default_path, sizeof (default_path));

	cv = xmms_config_property_register ("core.ipcsocket",
	                                    default_path,
	                                    on_config_ipcsocket_change,
	                                    NULL);

	if (!ipcpath) {
		/*
		 * if not ipcpath is specifed on the cmd line we
		 * grab it from the config
		 */
		ipcpath = xmms_config_property_get_string (cv);
	}

	if (!xmms_ipc_setup_server (ipcpath)) {
		xmms_ipc_shutdown ();
		xmms_log_fatal ("IPC failed to init!");
	}

	if (!xmms_plugin_init (ppath)) {
		return 1;
	}

	playlist = xmms_playlist_init ();
	xform_obj = xmms_xform_object_init ();
	bindata_obj = xmms_bindata_init ();

	mainobj = xmms_object_new (xmms_main_t, xmms_main_destroy);

	/* find output plugin. */
	cv = xmms_config_property_register ("output.plugin",
	                                    XMMS_OUTPUT_DEFAULT,
	                                    change_output, mainobj);

	if (outname) {
		xmms_config_property_set_data (cv, outname);
	}

	outname = xmms_config_property_get_string (cv);
	xmms_log_info ("Using output plugin: %s", outname);
	o_plugin = (xmms_output_plugin_t *)xmms_plugin_find (XMMS_PLUGIN_TYPE_OUTPUT, outname);
	if (!o_plugin) {
		xmms_log_error ("Baaaaad output plugin, try to change the"
		                "output.plugin config variable to something usefull");
	}

	mainobj->output = xmms_output_new (o_plugin, playlist);
	if (!mainobj->output) {
		xmms_log_fatal ("Failed to create output object!");
	}

	mainobj->vis = xmms_visualization_new (mainobj->output);

	if (status_fd != -1) {
		write (status_fd, "+", 1);
	}

	xmms_signal_init (XMMS_OBJECT (mainobj));

	xmms_ipc_object_register (XMMS_IPC_OBJECT_MAIN,
	                          XMMS_OBJECT (mainobj));

	xmms_ipc_broadcast_register (XMMS_OBJECT (mainobj),
	                             XMMS_IPC_SIGNAL_QUIT);

	xmms_object_cmd_add (XMMS_OBJECT (mainobj),
	                     XMMS_IPC_CMD_QUIT,
	                     XMMS_CMD_FUNC (quit));
	xmms_object_cmd_add (XMMS_OBJECT (mainobj),
	                     XMMS_IPC_CMD_HELLO,
	                     XMMS_CMD_FUNC (hello));
	xmms_object_cmd_add (XMMS_OBJECT (mainobj),
	                     XMMS_IPC_CMD_PLUGIN_LIST,
	                     XMMS_CMD_FUNC (plugin_list));
	xmms_object_cmd_add (XMMS_OBJECT (mainobj),
	                     XMMS_IPC_CMD_STATS,
	                     XMMS_CMD_FUNC (stats));

	/* Save the time we started in order to count uptime */
	mainobj->starttime = time (NULL);

	/* Dirty hack to tell XMMS_PATH a valid path */
	g_strlcpy (default_path, ipcpath, sizeof (default_path));

	tmp = strchr (default_path, ';');
	if (tmp) {
		*tmp = '\0';
	}

	g_setenv ("XMMS_PATH", default_path, TRUE);

	/* Also put the full path for clients that understands */
	g_setenv("XMMS_PATH_FULL", ipcpath, TRUE);

	tmp = XMMS_BUILD_PATH ("shutdown.d");
	cv = xmms_config_property_register ("core.shutdownpath",
	                                    tmp, NULL, NULL);
	g_free (tmp);

	tmp = XMMS_BUILD_PATH ("startup.d");
	cv = xmms_config_property_register ("core.startuppath",
	                                    tmp, NULL, NULL);
	g_free (tmp);

	/* Startup dir */
	do_scriptdir (xmms_config_property_get_string (cv), "start");

	mainloop = g_main_loop_new (NULL, FALSE);

	g_main_loop_run (mainloop);

	return 0;
}