/** * Adds a directory recursivly to the playlist. * * The url should be absolute to the server-side and url encoded. Note * that you will have to include the protocol for the url to. ie: * file://mp3/my_mp3s/first.mp3. You probably want to use * #xmmsc_playlist_radd unless you want to add a string that comes as * a result from the daemon, such as from #xmmsc_xform_media_browse * * @param c The connection structure. * @param playlist The playlist in which to add the media. * @param url Encoded path. * */ xmmsc_result_t * xmmsc_playlist_radd_encoded (xmmsc_connection_t *c, const char *playlist, const char *url) { xmms_ipc_msg_t *msg; x_check_conn (c, NULL); x_api_error_if (!url, "with a NULL url", NULL); if (!_xmmsc_medialib_verify_url (url)) x_api_error ("with a non encoded url", NULL); /* default to the active playlist */ if (playlist == NULL) { playlist = XMMS_ACTIVE_PLAYLIST; } msg = xmms_ipc_msg_new (XMMS_IPC_OBJECT_PLAYLIST, XMMS_IPC_CMD_RADD); xmms_ipc_msg_put_string (msg, playlist); xmms_ipc_msg_put_string (msg, url); return xmmsc_send_msg (c, msg); }
/** * List the properties of all media matched by the given collection. * A list of ordering properties can be specified, as well as offsets * to only retrieve part of the result set. The list of properties to * retrieve must be explicitely specified. It is also possible to * group by certain properties. * * @param conn The connection to the server. * @param coll The collection used to query. * @param order The list of properties to order by, passed as an * #xmmsv_t list of strings. * @param limit_start The offset at which to start retrieving results (0 to disable). * @param limit_len The maximum number of entries to retrieve (0 to disable). * @param fetch The list of properties to retrieve, passed as an * #xmmsv_t list of strings. At least one property is required. * @param group The list of properties to group by, passed as an * #xmmsv_t list of strings. */ xmmsc_result_t* xmmsc_coll_query_infos (xmmsc_connection_t *conn, xmmsv_coll_t *coll, xmmsv_t *order, int limit_start, int limit_len, xmmsv_t *fetch, xmmsv_t *group) { xmms_ipc_msg_t *msg; x_check_conn (conn, NULL); x_api_error_if (!coll, "with a NULL collection", NULL); x_api_error_if (!fetch, "with a NULL fetch list", NULL); /* default to empty ordering */ if (!order) { order = xmmsv_new_list (); } else { xmmsv_ref (order); } /* default to empty grouping */ if (!group) { group = xmmsv_new_list (); } else { xmmsv_ref (group); } msg = xmms_ipc_msg_new (XMMS_IPC_OBJECT_COLLECTION, XMMS_IPC_CMD_QUERY_INFOS); xmms_ipc_msg_put_collection (msg, coll); xmms_ipc_msg_put_int32 (msg, limit_start); xmms_ipc_msg_put_int32 (msg, limit_len); xmms_ipc_msg_put_value_list (msg, order); /* purposedly skip typing */ xmms_ipc_msg_put_value_list (msg, fetch); /* purposedly skip typing */ xmms_ipc_msg_put_value_list (msg, group); /* purposedly skip typing */ xmmsv_unref (order); xmmsv_unref (group); return xmmsc_send_msg (conn, msg); }
/** * Queries the medialib for media and adds the matching ones to * the current playlist. * * @param c The connection structure. * @param playlist The playlist in which to add the media. * @param coll The collection to find media in the medialib. * @param order The list of properties by which to order the matching * media, passed as an #xmmsv_t list of strings. */ xmmsc_result_t * xmmsc_playlist_add_collection (xmmsc_connection_t *c, const char *playlist, xmmsv_coll_t *coll, xmmsv_t *order) { xmms_ipc_msg_t *msg; x_check_conn (c, NULL); /* default to the active playlist */ if (playlist == NULL) { playlist = XMMS_ACTIVE_PLAYLIST; } /* default to empty ordering */ msg = xmms_ipc_msg_new (XMMS_IPC_OBJECT_PLAYLIST, XMMS_IPC_CMD_ADD_COLL); xmms_ipc_msg_put_string (msg, playlist); xmms_ipc_msg_put_collection (msg, coll); xmms_ipc_msg_put_value_list (msg, order); /* purposedly skip typing */ return xmmsc_send_msg (c, msg); }
static void process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg) { xmms_object_t *object; xmms_object_cmd_arg_t arg; xmms_ipc_msg_t *retmsg; xmmsv_t *error, *arguments; uint32_t objid, cmdid; g_return_if_fail (msg); objid = xmms_ipc_msg_get_object (msg); cmdid = xmms_ipc_msg_get_cmd (msg); if (!xmms_ipc_msg_get_value (msg, &arguments)) { xmms_log_error ("Cannot read command arguments. " "Ignoring command."); return; } if (objid == XMMS_IPC_OBJECT_SIGNAL) { if (cmdid == XMMS_IPC_CMD_SIGNAL) { xmms_ipc_register_signal (client, msg, arguments); } else if (cmdid == XMMS_IPC_CMD_BROADCAST) { xmms_ipc_register_broadcast (client, msg, arguments); } else { xmms_log_error ("Bad command id (%d) for signal object", cmdid); } goto out; } if (objid >= XMMS_IPC_OBJECT_END) { xmms_log_error ("Bad object id (%d)", objid); goto out; } g_mutex_lock (ipc_object_pool_lock); object = ipc_object_pool->objects[objid]; g_mutex_unlock (ipc_object_pool_lock); if (!object) { xmms_log_error ("Object %d was not found!", objid); goto out; } if (!g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid))) { xmms_log_error ("No such cmd %d on object %d", cmdid, objid); goto out; } xmms_object_cmd_arg_init (&arg); arg.args = arguments; xmms_object_cmd_call (object, cmdid, &arg); if (xmms_error_isok (&arg.error)) { retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); } else { /* FIXME: or we could omit setting the command to _CMD_ERROR * and let the client check whether the value it got is an * error xmmsv_t. If so, don't forget to * update the client-side of IPC too. */ retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); error = xmmsv_new_error (xmms_error_message_get (&arg.error)); xmms_ipc_msg_put_value (retmsg, error); xmmsv_unref (error); /* retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); */ } if (arg.retval) xmmsv_unref (arg.retval); err: xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg)); g_mutex_lock (client->lock); xmms_ipc_client_msg_write (client, retmsg); g_mutex_unlock (client->lock); out: if (arguments) { xmmsv_unref (arguments); } }
static void process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg) { xmms_object_t *object; xmms_object_cmd_desc_t *cmd = NULL; xmms_object_cmd_arg_t arg; xmms_ipc_msg_t *retmsg; xmmsv_t *error, *arguments; uint32_t objid, cmdid; gint i; g_return_if_fail (msg); objid = xmms_ipc_msg_get_object (msg); cmdid = xmms_ipc_msg_get_cmd (msg); if (!xmms_ipc_msg_get_value (msg, &arguments)) { xmms_log_error ("Cannot read command arguments. " "Ignoring command."); return; } if (objid == XMMS_IPC_OBJECT_SIGNAL) { if (cmdid == XMMS_IPC_CMD_SIGNAL) { xmms_ipc_register_signal (client, msg, arguments); } else if (cmdid == XMMS_IPC_CMD_BROADCAST) { xmms_ipc_register_broadcast (client, msg, arguments); } else { xmms_log_error ("Bad command id (%d) for signal object", cmdid); } goto out; } if (objid >= XMMS_IPC_OBJECT_END) { xmms_log_error ("Bad object id (%d)", objid); goto out; } g_mutex_lock (ipc_object_pool_lock); object = ipc_object_pool->objects[objid]; g_mutex_unlock (ipc_object_pool_lock); if (!object) { xmms_log_error ("Object %d was not found!", objid); goto out; } if (object->cmds) cmd = g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid)); if (!cmd) { xmms_log_error ("No such cmd %d on object %d", cmdid, objid); goto out; } xmms_object_cmd_arg_init (&arg); for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { if (!type_and_msg_to_arg (cmd->args[i], arguments, &arg, i)) { xmms_log_error ("Error parsing args"); if (objid == XMMS_IPC_OBJECT_MAIN && cmdid == XMMS_IPC_CMD_HELLO) { xmms_log_error ("Couldn't parse hello message. " "Maybe the client or libxmmsclient " "needs to be updated."); } retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); error = xmmsv_new_error ("Corrupt msg"); xmms_ipc_msg_put_value (retmsg, error); xmmsv_unref (error); goto err; } } xmms_object_cmd_call (object, cmdid, &arg); if (xmms_error_isok (&arg.error)) { retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); } else { /* FIXME: or we could omit setting the command to _CMD_ERROR * and let the client check whether the value it got is an * error xmmsv_t. If so, don't forget to * update the client-side of IPC too. */ retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); error = xmmsv_new_error (xmms_error_message_get (&arg.error)); xmms_ipc_msg_put_value (retmsg, error); xmmsv_unref (error); /* retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); */ } if (arg.retval) xmmsv_unref (arg.retval); err: for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { if (arg.values[i]) xmmsv_unref (arg.values[i]); } xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg)); g_mutex_lock (client->lock); xmms_ipc_client_msg_write (client, retmsg); g_mutex_unlock (client->lock); out: if (arguments) { xmmsv_unref (arguments); } }
static void process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg) { xmms_object_t *object; xmms_object_cmd_desc_t *cmd = NULL; xmms_object_cmd_arg_t arg; xmms_ipc_msg_t *retmsg; uint32_t objid, cmdid; gint i; g_return_if_fail (msg); objid = xmms_ipc_msg_get_object (msg); cmdid = xmms_ipc_msg_get_cmd (msg); if (objid == XMMS_IPC_OBJECT_SIGNAL && cmdid == XMMS_IPC_CMD_SIGNAL) { gint32 signalid; if (!xmms_ipc_msg_get_int32 (msg, &signalid)) { xmms_log_error ("No signalid in this msg?!"); return; } if (signalid < 0 || signalid >= XMMS_IPC_SIGNAL_END) { xmms_log_error ("Bad signal id (%d)", signalid); return; } g_mutex_lock (client->lock); client->pendingsignals[signalid] = xmms_ipc_msg_get_cookie (msg); g_mutex_unlock (client->lock); return; } else if (objid == XMMS_IPC_OBJECT_SIGNAL && cmdid == XMMS_IPC_CMD_BROADCAST) { gint32 broadcastid; if (!xmms_ipc_msg_get_int32 (msg, &broadcastid)) { xmms_log_error ("No broadcastid in this msg?!"); return; } if (broadcastid < 0 || broadcastid >= XMMS_IPC_SIGNAL_END) { xmms_log_error ("Bad broadcast id (%d)", broadcastid); return; } g_mutex_lock (client->lock); client->broadcasts[broadcastid] = g_list_append (client->broadcasts[broadcastid], GUINT_TO_POINTER (xmms_ipc_msg_get_cookie (msg))); g_mutex_unlock (client->lock); return; } if (objid >= XMMS_IPC_OBJECT_END) { xmms_log_error ("Bad object id (%d)", objid); return; } g_mutex_lock (ipc_object_pool_lock); object = ipc_object_pool->objects[objid]; g_mutex_unlock (ipc_object_pool_lock); if (!object) { xmms_log_error ("Object %d was not found!", objid); return; } if (cmdid >= XMMS_IPC_CMD_END) { xmms_log_error ("Bad command id (%d)", cmdid); return; } if (object->cmds) cmd = g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid)); if (!cmd) { xmms_log_error ("No such cmd %d on object %d", cmdid, objid); return; } xmms_object_cmd_arg_init (&arg); for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { if (!type_and_msg_to_arg (cmd->args[i], msg, &arg, i)) { xmms_log_error ("Error parsing args"); retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); xmms_ipc_msg_put_string (retmsg, "Corrupt msg"); goto err; } } xmms_object_cmd_call (object, cmdid, &arg); if (xmms_error_isok (&arg.error)) { retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); } else { /* FIXME: or we could change the client code to transform * CMD_ERROR to an error value_t. If so, don't forget to * update the client-side of IPC too. */ retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); xmms_ipc_msg_put_string (retmsg, xmms_error_message_get (&arg.error)); /* retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); */ } if (arg.retval) xmmsv_unref (arg.retval); err: for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { xmmsv_unref (arg.values[i]); } xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg)); g_mutex_lock (client->lock); xmms_ipc_client_msg_write (client, retmsg); g_mutex_unlock (client->lock); }