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 (); }
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; }
/** * 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; }
/** * 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)); }
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; }
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; }
/** * @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 (); }
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)); }
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); }
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; }
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)); }
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); }
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); }
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; }
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; }
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); }
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; }
/** * 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; }
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); }
/** * 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; }
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); } }
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); }
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; }
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; }
/** * 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; }
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; }
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; }
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; }
/** * 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; }