static void __int_xmms_cmd_remove (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 remove (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to remove"); return; } const char * argval0; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in remove"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in remove"); return; } if (!xmmsv_get_string (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in remove"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in remove"); return; } xmms_bindata_client_remove ((xmms_bindata_t *) object, argval0, &arg->error); arg->retval = xmmsv_new_none (); }
static void xmms_output_volume_set (xmms_output_t *output, const gchar *channel, guint volume, xmms_error_t *error) { if (!output->plugin) { xmms_error_set (error, XMMS_ERROR_GENERIC, "couldn't set volume, output plugin not loaded"); return; } if (!xmms_output_plugin_method_volume_set_available (output->plugin)) { xmms_error_set (error, XMMS_ERROR_GENERIC, "operation not supported"); return; } if (volume > 100) { xmms_error_set (error, XMMS_ERROR_INVAL, "volume out of range"); return; } if (!xmms_output_plugin_methods_volume_set (output->plugin, output, channel, volume)) { xmms_error_set (error, XMMS_ERROR_GENERIC, "couldn't set volume"); } }
/** * Retrieve the position of the currently active xmms_medialib_entry_t * */ xmmsv_t * xmms_playlist_client_current_pos (xmms_playlist_t *playlist, const gchar *plname, xmms_error_t *err) { guint32 pos; xmmsv_coll_t *plcoll; xmmsv_t *dict; g_return_val_if_fail (playlist, 0); g_mutex_lock (playlist->mutex); plcoll = xmms_playlist_get_coll (playlist, plname, err); if (plcoll == NULL) { g_mutex_unlock (playlist->mutex); xmms_error_set (err, XMMS_ERROR_INVAL, "no such playlist"); return 0; } pos = xmms_playlist_coll_get_currpos (plcoll); if (pos == -1) { xmms_error_set (err, XMMS_ERROR_GENERIC, "no current entry"); } g_mutex_unlock (playlist->mutex); dict = xmms_playlist_current_pos_msg_new (playlist, pos, plname); return dict; }
/** * Retrieve a copy of the name of the currently active playlist. * */ static gchar * xmms_playlist_client_current_active (xmms_playlist_t *playlist, xmms_error_t *err) { gchar *alias = NULL; xmmsv_coll_t *active_coll; g_return_val_if_fail (playlist, 0); g_mutex_lock (playlist->mutex); active_coll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err); if (active_coll != NULL) { alias = xmms_collection_find_alias (playlist->colldag, XMMS_COLLECTION_NSID_PLAYLISTS, active_coll, XMMS_ACTIVE_PLAYLIST); if (alias == NULL) { xmms_error_set (err, XMMS_ERROR_GENERIC, "active playlist not referenced!"); } } else { xmms_error_set (err, XMMS_ERROR_GENERIC, "no active playlist"); } g_mutex_unlock (playlist->mutex); return alias; }
static void __int_xmms_cmd_add (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 add (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to add"); return; } GString * argval0; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in add"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in add"); return; } if (!xmms_bin_to_gstring (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in add"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in add"); return; } gchar * retval = xmms_bindata_client_add ((xmms_bindata_t *) object, argval0, &arg->error); if (retval != NULL) { arg->retval = xmms_convert_and_kill_string (retval); } }
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)); }
static xmms_fetch_spec_t * xmms_fetch_spec_new_organize (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmms_fetch_spec_t *spec; xmmsv_dict_iter_t *it; s4_sourcepref_t *sp; xmmsv_t *org_data; gint org_idx; if (!xmmsv_dict_get (fetch, "data", &org_data)) { xmms_error_set (err, XMMS_ERROR_INVAL, "Required field 'data' not set in organize."); return NULL; } if (xmmsv_get_type (org_data) != XMMSV_TYPE_DICT) { xmms_error_set (err, XMMS_ERROR_INVAL, "Field 'data' in organize must be a dict."); return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { return NULL; } spec = g_new0 (xmms_fetch_spec_t, 1); spec->type = FETCH_ORGANIZE; spec->data.organize.count = xmmsv_dict_get_size (org_data); spec->data.organize.keys = g_new0 (const char *, spec->data.organize.count); spec->data.organize.data = g_new0 (xmms_fetch_spec_t *, spec->data.organize.count); org_idx = 0; xmmsv_get_dict_iter (org_data, &it); while (xmmsv_dict_iter_valid (it)) { xmms_fetch_spec_t *orgee; const gchar *str; xmmsv_t *entry; xmmsv_dict_iter_pair (it, &str, &entry); orgee = xmms_fetch_spec_new (entry, info, sp, err); if (xmms_error_iserror (err)) { xmms_fetch_spec_free (spec); spec = NULL; break; } spec->data.organize.keys[org_idx] = str; spec->data.organize.data[org_idx] = orgee; org_idx++; xmmsv_dict_iter_next (it); } xmmsv_dict_iter_explicit_destroy (it); s4_sourcepref_unref (sp); return spec; }
static int32_t xmms_visualization_client_set_properties (xmms_visualization_t *vis, int32_t id, xmmsv_t* prop, xmms_error_t *err) { xmms_vis_client_t *c; xmmsv_dict_iter_t *it; const gchar *key, *valstr; xmmsv_t *value; x_fetch_client (id); if (!xmmsv_get_type (prop) == XMMSV_TYPE_DICT) { xmms_error_set (err, XMMS_ERROR_INVAL, "properties must be sent as a dict!"); } else { /* record every pair */ xmmsv_get_dict_iter (prop, &it); while (xmmsv_dict_iter_valid (it)) { if (!xmmsv_dict_iter_pair (it, &key, &value)) { xmms_error_set (err, XMMS_ERROR_INVAL, "key-value property pair could not be read!"); } else if (!xmmsv_get_string (value, &valstr)) { xmms_error_set (err, XMMS_ERROR_INVAL, "property value could not be read!"); } else if (!property_set (&c->prop, key, valstr)) { xmms_error_set (err, XMMS_ERROR_INVAL, "property could not be set!"); } xmmsv_dict_iter_next (it); } /* TODO: propagate new format to xform! */ } x_release_client (); return (++c->format); }
static void __int_xmms_cmd_rehash (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 rehash (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to rehash"); return; } gint32 argval0; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in rehash"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in rehash"); return; } if (!xmmsv_get_int (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in rehash"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in rehash"); return; } xmms_medialib_client_rehash ((xmms_medialib_t *) object, argval0, &arg->error); arg->retval = xmmsv_new_none (); }
/** * Insert an entry at a given position in the playlist without * validating it. * * @internal */ void xmms_playlist_insert_entry (xmms_playlist_t *playlist, const gchar *plname, guint32 pos, xmms_medialib_entry_t file, xmms_error_t *err) { xmms_medialib_session_t *session; xmmsv_t *dict; gint currpos; gint len; xmmsv_coll_t *plcoll; gboolean valid; g_mutex_lock (playlist->mutex); do { session = xmms_medialib_session_begin_ro (playlist->medialib); valid = xmms_medialib_check_id (session, file); } while (!xmms_medialib_session_commit (session)); if (!valid) { g_mutex_unlock (playlist->mutex); xmms_error_set (err, XMMS_ERROR_NOENT, "That is not a valid medialib id!"); return; } plcoll = xmms_playlist_get_coll (playlist, plname, err); if (plcoll == NULL) { /* FIXME: happens ? */ g_mutex_unlock (playlist->mutex); return; } len = xmms_playlist_coll_get_size (plcoll); if (pos > len) { xmms_error_set (err, XMMS_ERROR_GENERIC, "Could not insert entry outside of playlist!"); g_mutex_unlock (playlist->mutex); return; } xmmsv_coll_idlist_insert (plcoll, pos, file); /** propagate the MID ! */ dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_INSERT, file, plname); xmmsv_dict_set_int (dict, "position", pos); xmms_playlist_changed_msg_send (playlist, dict); /** update position once client is familiar with the new item. */ currpos = xmms_playlist_coll_get_currpos (plcoll); if (pos <= currpos) { currpos++; xmms_collection_set_int_attr (plcoll, "position", currpos); XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname); } g_mutex_unlock (playlist->mutex); }
static gint xmms_mpc_read (xmms_xform_t *xform, xmms_sample_t *buffer, gint len, xmms_error_t *err) { MPC_SAMPLE_FORMAT internal[MPC_DECODER_BUFFER_LENGTH]; xmms_mpc_data_t *data; mpc_uint32_t ret; guint size; data = xmms_xform_private_data_get (xform); size = MIN (data->buffer->len, len); #ifdef HAVE_MPCDEC_OLD if (size <= 0) { ret = mpc_decoder_decode (&data->decoder, internal, NULL, NULL); if (ret == -1) { xmms_error_set (err, XMMS_ERROR_GENERIC, "Musepack decoder failed"); return -1; } ret *= xmms_sample_size_get (XMMS_SAMPLE_FORMAT_FLOAT); ret *= data->info.channels; g_string_append_len (data->buffer, (gchar *) internal, ret); } #else if (size <= 0) { mpc_frame_info frame; frame.buffer = internal; do { ret = mpc_demux_decode (data->demux, &frame); } while (frame.bits != -1 && frame.samples == 0); if (frame.bits == -1 && ret != MPC_STATUS_OK) { xmms_error_set (err, XMMS_ERROR_GENERIC, "Musepack decoder failed"); return -1; } ret = frame.samples; ret *= xmms_sample_size_get (XMMS_SAMPLE_FORMAT_FLOAT); ret *= data->info.channels; g_string_append_len (data->buffer, (gchar *) internal, ret); } #endif /* Update the current size of available data */ size = MIN (data->buffer->len, len); memcpy (buffer, data->buffer->str, size); g_string_erase (data->buffer, 0, size); return size; }
static xmmsv_t * normalize_metadata_fields (xmmsv_t *fetch, xmms_error_t *err) { gpointer SENTINEL = GINT_TO_POINTER (0x31337); GHashTable *table; xmmsv_list_iter_t *it; xmmsv_t *fields; if (!xmmsv_dict_get (fetch, "fields", &fields)) { /* No fields means that we should fetch all fields */ return NULL; } if (xmmsv_get_type (fields) != XMMSV_TYPE_LIST) { const gchar *message = "'fields' must be a list of strings."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } if (xmmsv_list_get_size (fields) < 1) { /* No fields means that we should fetch all fields */ return NULL; } table = g_hash_table_new (g_str_hash, g_str_equal); xmmsv_get_list_iter (fields, &it); while (xmmsv_list_iter_valid (it)) { const gchar *value = NULL; if (!xmmsv_list_iter_entry_string (it, &value)) { const gchar *message = "'fields' entries must be of string type."; xmms_error_set (err, XMMS_ERROR_INVAL, message); g_hash_table_unref (table); return NULL; } if (g_hash_table_lookup (table, (gpointer) value) == SENTINEL) { const gchar *message = "'fields' entries must be unique."; xmms_error_set (err, XMMS_ERROR_INVAL, message); g_hash_table_unref (table); return NULL; } g_hash_table_insert (table, (gpointer) value, SENTINEL); xmmsv_list_iter_next (it); } g_hash_table_unref (table); return fields; }
static void __int_xmms_cmd_set_property_int (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { xmmsv_t *t; if (xmmsv_list_get_size (arg->args) != 4) { XMMS_DBG ("Wrong number of arguments to set_property_int (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to set_property_int"); return; } gint32 argval0; const char * argval1; const char * argval2; gint32 argval3; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in set_property_int"); return; } if (!xmmsv_get_int (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in set_property_int"); return; } if (!xmmsv_list_get (arg->args, 1, &t)) { XMMS_DBG ("Missing arg 1 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 1 in set_property_int"); return; } if (!xmmsv_get_string (t, &argval1)) { XMMS_DBG ("Error parsing arg 1 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 1 in set_property_int"); return; } if (!xmmsv_list_get (arg->args, 2, &t)) { XMMS_DBG ("Missing arg 2 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 2 in set_property_int"); return; } if (!xmmsv_get_string (t, &argval2)) { XMMS_DBG ("Error parsing arg 2 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 2 in set_property_int"); return; } if (!xmmsv_list_get (arg->args, 3, &t)) { XMMS_DBG ("Missing arg 3 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 3 in set_property_int"); return; } if (!xmmsv_get_int (t, &argval3)) { XMMS_DBG ("Error parsing arg 3 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 3 in set_property_int"); return; } xmms_medialib_client_set_property_int ((xmms_medialib_t *) object, argval0, argval1, argval2, argval3, &arg->error); arg->retval = xmmsv_new_none (); }
static gint64 xmms_wave_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *error) { xmms_wave_data_t *data; gint64 offset; gint64 ret; g_return_val_if_fail (xform, -1); g_return_val_if_fail (samples >= 0, -1); g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1); data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); /* in mp3 mode, the samples argument actually indicates bytes.. * thus we've set up bits_per_sample to 8 and channels to 1 to get * expected behaviour. */ offset = data->header_size; offset += samples * (data->bits_per_sample / 8) * data->channels; if (offset < data->header_size) { xmms_error_set (error, XMMS_ERROR_INVAL, "Trying to seek before start of stream"); return -1; } if (offset > data->header_size + data->bytes_total) { xmms_error_set (error, XMMS_ERROR_INVAL, "Trying to seek past end of stream"); return -1; } ret = xmms_xform_seek (xform, offset, whence, error); if (ret == -1) { return -1; } if (ret != offset) { XMMS_DBG ("xmms_xform_seek didn't return expected offset " "(%" G_GINT64_FORMAT " != %" G_GINT64_FORMAT ")", ret, offset); } ret -= data->header_size; ret /= (data->bits_per_sample / 8) * data->channels; return ret; }
static gboolean xmms_xspf_browse (xmms_xform_t *xform, const gchar *url, xmms_error_t *error) { int ret; char buf[4096]; xmlParserCtxtPtr ctx; xmlDocPtr doc; g_return_val_if_fail (xform, FALSE); xmms_error_reset (error); ctx = xmlCreatePushParserCtxt (NULL, NULL, buf, 0, NULL); if (!ctx) { xmms_error_set (error, XMMS_ERROR_OOM, "Could not allocate xml parser"); return FALSE; } while ((ret = xmms_xform_read (xform, buf, sizeof (buf), error)) > 0) { if ((xmlParseChunk (ctx, buf, ret, 0)) != 0) { break; } } if (ret < 0) { xmms_error_set (error, XMMS_ERROR_GENERIC, "failed to read data from previous xform"); xmlFreeParserCtxt (ctx); return FALSE; } xmlParseChunk (ctx, buf, 0, 1); if (ctx->lastError.message) { xmms_error_set (error, XMMS_ERROR_INVAL, ctx->lastError.message); xmlFreeParserCtxt (ctx); return FALSE; } doc = ctx->myDoc; if (!xmms_xspf_browse_add_entries (xform, doc, error)) { xmlFreeParserCtxt (ctx); return FALSE; } xmms_error_reset (error); xmlFreeParserCtxt (ctx); return TRUE; }
static GTree * xmms_output_volume_get (xmms_output_t *output, xmms_error_t *error) { GTree *ret; xmms_volume_map_t map; if (!output->plugin) { xmms_error_set (error, XMMS_ERROR_GENERIC, "couldn't get volume, output plugin not loaded"); return NULL; } if (!xmms_output_plugin_method_volume_get_available (output->plugin)) { xmms_error_set (error, XMMS_ERROR_GENERIC, "operation not supported"); return NULL; } xmms_error_set (error, XMMS_ERROR_GENERIC, "couldn't get volume"); xmms_volume_map_init (&map); /* ask the plugin how much channels it would like to set */ if (!xmms_output_plugin_method_volume_get (output->plugin, output, NULL, NULL, &map.num_channels)) { return NULL; } /* check for sane values */ g_return_val_if_fail (map.num_channels > 0, NULL); g_return_val_if_fail (map.num_channels <= VOLUME_MAX_CHANNELS, NULL); map.names = g_new (const gchar *, map.num_channels); map.values = g_new (guint, map.num_channels); map.status = xmms_output_plugin_method_volume_get (output->plugin, output, map.names, map.values, &map.num_channels); if (!map.status || !map.num_channels) { return NULL; /* error is set (-> no leak) */ } ret = xmms_volume_map_to_dict (&map); /* success! */ xmms_error_reset (error); return ret; }
static gboolean xmms_rss_browse (xmms_xform_t *xform, const gchar *url, xmms_error_t *error) { int ret; char buffer[1024]; xmlSAXHandler handler; xmlParserCtxtPtr ctx; xmms_rss_data_t data; g_return_val_if_fail (xform, FALSE); memset (&handler, 0, sizeof (handler)); memset (&data, 0, sizeof (data)); handler.startElement = (startElementSAXFunc) xmms_rss_start_element; handler.error = (errorSAXFunc) xmms_rss_error; handler.fatalError = (fatalErrorSAXFunc) xmms_rss_error; data.xform = xform; data.error = error; data.parse_failure = FALSE; xmms_error_reset (error); ctx = xmlCreatePushParserCtxt (&handler, &data, buffer, 0, NULL); if (!ctx) { xmms_error_set (error, XMMS_ERROR_OOM, "Could not allocate xml parser"); return FALSE; } while ((ret = xmms_xform_read (xform, buffer, sizeof (buffer), error)) > 0) { xmlParseChunk (ctx, buffer, ret, 0); } if (ret < 0) { xmms_error_set (error, XMMS_ERROR_GENERIC, "xmms_xform_read failed"); return FALSE; } if (data.parse_failure) return FALSE; xmlParseChunk (ctx, buffer, 0, 1); xmms_error_reset (error); xmlFreeParserCtxt (ctx); return TRUE; }
/** * Sanitize the 'get' property of a 'metadata' fetch specification. */ static xmmsv_t * normalize_metadata_get (xmmsv_t *fetch, xmms_error_t *err) { xmmsv_list_iter_t *it; xmmsv_t *get, *list; guint32 values; if (!xmmsv_dict_get (fetch, "get", &get) || xmmsv_get_type (get) != XMMSV_TYPE_LIST || xmmsv_list_get_size (get) < 1) { const gchar *message = "'get' must be a non-empty list of strings."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } list = xmmsv_new_list (); values = 0; /* Scan for duplicates or invalid values */ xmmsv_get_list_iter (get, &it); while (xmmsv_list_iter_valid (it)) { const gchar *value = NULL; guint32 get_as_int, mask; xmmsv_list_iter_entry_string (it, &value); if (!metadata_value_from_string (value, &get_as_int)) { const gchar *message = "'get' entries must be 'id', 'field', 'value' or 'source'."; xmms_error_set (err, XMMS_ERROR_INVAL, message); xmmsv_unref (list); return NULL; } mask = 1 << (get_as_int + 1); if (values & mask) { const gchar *message = "'get' entries must be unique."; xmms_error_set (err, XMMS_ERROR_INVAL, message); xmmsv_unref (list); return NULL; } values |= mask; xmmsv_list_append_int (list, get_as_int); xmmsv_list_iter_next (it); } return list; }
static s4_sourcepref_t * normalize_source_preferences (xmmsv_t *fetch, s4_sourcepref_t *prefs, xmms_error_t *err) { s4_sourcepref_t *sp; xmmsv_list_iter_t *it; const char **strv; const gchar *str; xmmsv_t *list; gint length, idx; if (!xmmsv_dict_get (fetch, "source-preference", &list)) { return s4_sourcepref_ref (prefs); } if (xmmsv_get_type (list) != XMMSV_TYPE_LIST) { const gchar *message = "'source-preference' must be a list of strings."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } length = xmmsv_list_get_size (list); if (length == 0) { return s4_sourcepref_ref (prefs); } strv = g_new0 (const char *, length + 1); idx = 0; xmmsv_get_list_iter (list, &it); while (xmmsv_list_iter_valid (it)) { if (!xmmsv_list_iter_entry_string (it, &str)) { const gchar *message = "'source-preference' must be a list of strings."; xmms_error_set (err, XMMS_ERROR_INVAL, message); g_free (strv); return NULL; } strv[idx++] = str; xmmsv_list_iter_next (it); } sp = s4_sourcepref_create (strv); g_free (strv); return sp; }
/** * Extract hostname, port and command from an url. * daap://hostname:port/command */ static gboolean get_data_from_url (const gchar *url, gchar **host, guint *port, gchar **cmd, xmms_error_t *err) { const gchar *port_ptr, *cmd_ptr, *end_ptr, *stripped; stripped = url + sizeof (gchar) * strlen ("daap://"); end_ptr = stripped + sizeof (gchar) * strlen (stripped); if (stripped == end_ptr) { xmms_error_set (err, XMMS_ERROR_INVAL, "Empty URL"); return FALSE; } port_ptr = strstr (stripped, ":"); if (port && port_ptr && (port_ptr + 1) != end_ptr) { *port = strtol (port_ptr + 1, (gchar **) NULL, 10); if (*port == 0) { *port = DEFAULT_DAAP_PORT; } } else if (port) { *port = DEFAULT_DAAP_PORT; } cmd_ptr = strstr (stripped, "/"); if (cmd && cmd_ptr && (cmd_ptr + 1) != end_ptr) { *cmd = g_strdup (cmd_ptr); } else if (cmd) { /* cmd wanted but not found */ xmms_error_set (err, XMMS_ERROR_INVAL, "No file requested"); } else if (!cmd && cmd_ptr && (cmd_ptr + 1) != end_ptr) { /* cmd not wanted but found */ xmms_error_set (err, XMMS_ERROR_NOENT, "No such directory"); return FALSE; } if (host) { if (port_ptr) { *host = g_strndup (stripped, port_ptr - stripped); } else if (cmd_ptr) { *host = g_strndup (stripped, cmd_ptr - stripped); } else { *host = g_strdup (stripped); } } return TRUE; }
guint daap_command_login (gchar *host, gint port, guint request_id, xmms_error_t *err) { xmms_daap_conn_t *conn; cc_data_t *cc_data; guint session_id = 0; conn = daap_conn_new (host, port); if (!conn) { xmms_error_set (err, XMMS_ERROR_GENERIC, "Connection to server failed! " "Please make sure the url is of the form:\n" "daap://ip[:port]/[song]"); return 0; } cc_data = daap_request_data (conn->chan, "/login", host, request_id); if (cc_data) { session_id = cc_data->session_id; cc_data_free (cc_data); } daap_conn_free (conn); return session_id; }
int32_t init_shm (xmms_visualization_t *vis, int32_t id, int32_t shmid, xmms_error_t *err) { xmms_error_set (err, XMMS_ERROR_NO_SAUSAGE, "Shared Memory not supported by this platform!"); return -1; }
static gint64 xmms_samba_seek (xmms_xform_t *xform, gint64 offset, xmms_xform_seek_mode_t whence, xmms_error_t *error) { xmms_samba_data_t *data; gint w = 0; off_t res; g_return_val_if_fail (xform, -1); data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); switch (whence) { case XMMS_XFORM_SEEK_SET: w = SEEK_SET; break; case XMMS_XFORM_SEEK_END: w = SEEK_END; break; case XMMS_XFORM_SEEK_CUR: w = SEEK_CUR; break; } G_LOCK (mutex); res = smbc_lseek (data->fd, offset, w); G_UNLOCK (mutex); if (res == -1) { xmms_error_set (error, XMMS_ERROR_INVAL, "Couldn't seek"); } return res; }
static gboolean xmms_gvfs_browse (xmms_xform_t *xform, const gchar *url, xmms_error_t *error) { GError *err = NULL; GFile *file; GFileInfo *info; GFileEnumerator *enumerator; /* Same hack as in _init */ if (!g_ascii_strncasecmp (url, "file://", 7)) { file = g_file_new_for_path (url+7); } else { file = g_file_new_for_uri (url); } enumerator = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, &err); g_object_unref (file); if (!enumerator) { xmms_error_set (error, XMMS_ERROR_GENERIC, err->message); return FALSE; } while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL))) { guint32 child_type, flags = 0; guint64 child_size; const gchar *child_name; child_name = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME); child_type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE); child_size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE); if (child_type & G_FILE_TYPE_DIRECTORY) { flags |= XMMS_XFORM_BROWSE_FLAG_DIR; } xmms_xform_browse_add_entry (xform, child_name, flags); if (~child_type & G_FILE_TYPE_DIRECTORY) { xmms_xform_browse_add_entry_property_int (xform, XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE, child_size); } g_object_unref (info); } g_file_enumerator_close (enumerator, NULL, NULL); return TRUE; }
guint daap_command_login (gchar *host, gint port, guint request_id, xmms_error_t *err) { GIOChannel *chan; cc_data_t *cc_data; guint session_id = 0; chan = daap_open_connection (host, port); if (!chan) { xmms_error_set (err, XMMS_ERROR_GENERIC, "Connection to server failed! " "Please make sure the url is of the form:\n" "daap://ip[:port]/[song]"); return 0; } cc_data = daap_request_data (chan, "/login", host, request_id); if (cc_data) { session_id = cc_data->session_id; cc_data_free (cc_data); } g_io_channel_shutdown (chan, TRUE, NULL); g_io_channel_unref (chan); return session_id; }
static gint64 xmms_gvfs_seek (xmms_xform_t *xform, gint64 offset, xmms_xform_seek_mode_t whence, xmms_error_t *error) { GSeekType type; GError *err = NULL; xmms_gvfs_data_t *data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); g_return_val_if_fail (!g_input_stream_is_closed (data->handle), -1); switch (whence) { case XMMS_XFORM_SEEK_CUR: type = G_SEEK_CUR; break; case XMMS_XFORM_SEEK_SET: type = G_SEEK_SET; break; case XMMS_XFORM_SEEK_END: type = G_SEEK_END; break; } if (g_seekable_seek (G_SEEKABLE (data->handle), offset, type, NULL, &err)) { return g_seekable_tell (G_SEEKABLE (data->handle)); } xmms_error_set (error, XMMS_ERROR_GENERIC, err->message); return -1; }
static gboolean xmms_playlist_remove_unlocked (xmms_playlist_t *playlist, const gchar *plname, xmmsv_coll_t *plcoll, guint pos, xmms_error_t *err) { gint currpos; xmmsv_t *dict; g_return_val_if_fail (playlist, FALSE); currpos = xmms_playlist_coll_get_currpos (plcoll); if (!xmmsv_coll_idlist_remove (plcoll, pos)) { if (err) xmms_error_set (err, XMMS_ERROR_NOENT, "Entry was not in list!"); return FALSE; } dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_REMOVE, 0, plname); xmmsv_dict_set_int (dict, "position", pos); xmms_playlist_changed_msg_send (playlist, dict); /* decrease current position if removed entry was before or if it's * the current entry, but only if current position is a valid entry. */ if (currpos != -1 && pos <= currpos) { currpos = MAX (0, currpos - 1); xmms_collection_set_int_attr (plcoll, "position", currpos); XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname); } return TRUE; }
static void xmms_medialib_client_remove_property (xmms_medialib_t *medialib, xmms_medialib_entry_t entry, const gchar *source, const gchar *key, xmms_error_t *error) { xmms_medialib_session_t *session; do { session = xmms_medialib_session_begin (medialib); if (g_ascii_strcasecmp (source, "server") == 0) { xmms_error_set (error, XMMS_ERROR_GENERIC, "Can't remove properties set by the server!"); } else if (xmms_medialib_check_id (session, entry)) { xmms_medialib_property_remove (session, entry, source, key, error); } else { xmms_error_set (error, XMMS_ERROR_NOENT, "No such entry"); } } while (!xmms_medialib_session_commit (session)); }
/** * @internal Function to respond to the 'hello' sent from clients on connect */ static void xmms_main_client_hello (xmms_object_t *object, gint protocolver, const gchar *client, xmms_error_t *error) { if (protocolver != XMMS_IPC_PROTOCOL_VERSION) { xmms_log_info ("Client '%s' with bad protocol version (%d, not %d) connected", client, protocolver, XMMS_IPC_PROTOCOL_VERSION); xmms_error_set (error, XMMS_ERROR_INVAL, "Bad protocol version"); return; } XMMS_DBG ("Client '%s' connected", client); }
static gint xmms_mpg123_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err) { xmms_mpg123_data_t *data; int result = MPG123_OK; size_t read = 0; data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); while (read == 0) { gint ret = 0; if (result == MPG123_NEED_MORE) { ret = xmms_xform_read (xform, data->buf, BUFSIZE, err); if (ret < 0) { return ret; } else if (ret == 0) { data->eof_found = TRUE; } } result = mpg123_decode (data->decoder, data->buf, (size_t) ret, buf, len, &read); if (result == MPG123_NEED_MORE && data->eof_found) { /* We need more data, but there's none available * so libmpg123 apparently missed an EOF */ result = MPG123_DONE; break; } else if (result != MPG123_OK && result != MPG123_NEED_MORE) { /* This is some uncommon result like EOF, handle outside * the loop */ break; } } if (result == MPG123_DONE) { /* This is just normal EOF reported from libmpg123 */ XMMS_DBG ("Got EOF while decoding stream"); return 0; } else if (result == MPG123_NEW_FORMAT) { /* FIXME: When we can handle format changes, modify this */ xmms_error_set (err, XMMS_ERROR_GENERIC, "The output format changed, XMMS2 can't handle that"); return -1; } else if (result == MPG123_ERR) { xmms_error_set (err, XMMS_ERROR_GENERIC, mpg123_strerror (data->decoder)); return -1; } return (gint) read; }