153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2009 Tanu Kaskinen 553a5a1b3Sopenharmony_ci 653a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 753a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as published 853a5a1b3Sopenharmony_ci by the Free Software Foundation; either version 2.1 of the License, 953a5a1b3Sopenharmony_ci or (at your option) any later version. 1053a5a1b3Sopenharmony_ci 1153a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1253a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1353a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1453a5a1b3Sopenharmony_ci General Public License for more details. 1553a5a1b3Sopenharmony_ci 1653a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1753a5a1b3Sopenharmony_ci along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1853a5a1b3Sopenharmony_ci***/ 1953a5a1b3Sopenharmony_ci 2053a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2153a5a1b3Sopenharmony_ci#include <config.h> 2253a5a1b3Sopenharmony_ci#endif 2353a5a1b3Sopenharmony_ci 2453a5a1b3Sopenharmony_ci#include <ctype.h> 2553a5a1b3Sopenharmony_ci 2653a5a1b3Sopenharmony_ci#include <dbus/dbus.h> 2753a5a1b3Sopenharmony_ci 2853a5a1b3Sopenharmony_ci#include <pulse/utf8.h> 2953a5a1b3Sopenharmony_ci#include <pulse/xmalloc.h> 3053a5a1b3Sopenharmony_ci 3153a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h> 3253a5a1b3Sopenharmony_ci#include <pulsecore/dbus-util.h> 3353a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3453a5a1b3Sopenharmony_ci#include <pulsecore/namereg.h> 3553a5a1b3Sopenharmony_ci#include <pulsecore/protocol-dbus.h> 3653a5a1b3Sopenharmony_ci#include <pulsecore/socket-util.h> 3753a5a1b3Sopenharmony_ci#include <pulsecore/strbuf.h> 3853a5a1b3Sopenharmony_ci 3953a5a1b3Sopenharmony_ci#include "iface-card.h" 4053a5a1b3Sopenharmony_ci#include "iface-client.h" 4153a5a1b3Sopenharmony_ci#include "iface-device.h" 4253a5a1b3Sopenharmony_ci#include "iface-memstats.h" 4353a5a1b3Sopenharmony_ci#include "iface-module.h" 4453a5a1b3Sopenharmony_ci#include "iface-sample.h" 4553a5a1b3Sopenharmony_ci#include "iface-stream.h" 4653a5a1b3Sopenharmony_ci 4753a5a1b3Sopenharmony_ci#include "iface-core.h" 4853a5a1b3Sopenharmony_ci 4953a5a1b3Sopenharmony_ci#define INTERFACE_REVISION 0 5053a5a1b3Sopenharmony_ci 5153a5a1b3Sopenharmony_cistatic void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata); 5253a5a1b3Sopenharmony_cistatic void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata); 5353a5a1b3Sopenharmony_cistatic void handle_get_version(DBusConnection *conn, DBusMessage *msg, void *userdata); 5453a5a1b3Sopenharmony_cistatic void handle_get_is_local(DBusConnection *conn, DBusMessage *msg, void *userdata); 5553a5a1b3Sopenharmony_cistatic void handle_get_username(DBusConnection *conn, DBusMessage *msg, void *userdata); 5653a5a1b3Sopenharmony_cistatic void handle_get_hostname(DBusConnection *conn, DBusMessage *msg, void *userdata); 5753a5a1b3Sopenharmony_cistatic void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata); 5853a5a1b3Sopenharmony_cistatic void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); 5953a5a1b3Sopenharmony_cistatic void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); 6053a5a1b3Sopenharmony_cistatic void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); 6153a5a1b3Sopenharmony_cistatic void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); 6253a5a1b3Sopenharmony_cistatic void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); 6353a5a1b3Sopenharmony_cistatic void handle_get_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); 6453a5a1b3Sopenharmony_cistatic void handle_set_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); 6553a5a1b3Sopenharmony_cistatic void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userdata); 6653a5a1b3Sopenharmony_cistatic void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata); 6753a5a1b3Sopenharmony_cistatic void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); 6853a5a1b3Sopenharmony_cistatic void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); 6953a5a1b3Sopenharmony_cistatic void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata); 7053a5a1b3Sopenharmony_cistatic void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata); 7153a5a1b3Sopenharmony_cistatic void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); 7253a5a1b3Sopenharmony_cistatic void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata); 7353a5a1b3Sopenharmony_cistatic void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata); 7453a5a1b3Sopenharmony_cistatic void handle_get_samples(DBusConnection *conn, DBusMessage *msg, void *userdata); 7553a5a1b3Sopenharmony_cistatic void handle_get_modules(DBusConnection *conn, DBusMessage *msg, void *userdata); 7653a5a1b3Sopenharmony_cistatic void handle_get_clients(DBusConnection *conn, DBusMessage *msg, void *userdata); 7753a5a1b3Sopenharmony_cistatic void handle_get_my_client(DBusConnection *conn, DBusMessage *msg, void *userdata); 7853a5a1b3Sopenharmony_cistatic void handle_get_extensions(DBusConnection *conn, DBusMessage *msg, void *userdata); 7953a5a1b3Sopenharmony_ci 8053a5a1b3Sopenharmony_cistatic void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata); 8153a5a1b3Sopenharmony_ci 8253a5a1b3Sopenharmony_cistatic void handle_get_card_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata); 8353a5a1b3Sopenharmony_cistatic void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata); 8453a5a1b3Sopenharmony_cistatic void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata); 8553a5a1b3Sopenharmony_cistatic void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata); 8653a5a1b3Sopenharmony_cistatic void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *userdata); 8753a5a1b3Sopenharmony_cistatic void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *userdata); 8853a5a1b3Sopenharmony_cistatic void handle_exit(DBusConnection *conn, DBusMessage *msg, void *userdata); 8953a5a1b3Sopenharmony_cistatic void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata); 9053a5a1b3Sopenharmony_cistatic void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata); 9153a5a1b3Sopenharmony_ci 9253a5a1b3Sopenharmony_cistruct pa_dbusiface_core { 9353a5a1b3Sopenharmony_ci pa_core *core; 9453a5a1b3Sopenharmony_ci 9553a5a1b3Sopenharmony_ci pa_dbus_protocol *dbus_protocol; 9653a5a1b3Sopenharmony_ci 9753a5a1b3Sopenharmony_ci pa_hashmap *cards; 9853a5a1b3Sopenharmony_ci pa_hashmap *sinks_by_index; 9953a5a1b3Sopenharmony_ci pa_hashmap *sinks_by_path; 10053a5a1b3Sopenharmony_ci pa_hashmap *sources_by_index; 10153a5a1b3Sopenharmony_ci pa_hashmap *sources_by_path; 10253a5a1b3Sopenharmony_ci pa_hashmap *playback_streams; 10353a5a1b3Sopenharmony_ci pa_hashmap *record_streams; 10453a5a1b3Sopenharmony_ci pa_hashmap *samples; 10553a5a1b3Sopenharmony_ci pa_hashmap *modules; 10653a5a1b3Sopenharmony_ci pa_hashmap *clients; 10753a5a1b3Sopenharmony_ci 10853a5a1b3Sopenharmony_ci pa_sink *fallback_sink; 10953a5a1b3Sopenharmony_ci pa_source *fallback_source; 11053a5a1b3Sopenharmony_ci 11153a5a1b3Sopenharmony_ci pa_hook_slot *module_new_slot; 11253a5a1b3Sopenharmony_ci pa_hook_slot *module_removed_slot; 11353a5a1b3Sopenharmony_ci pa_hook_slot *default_sink_changed_slot; 11453a5a1b3Sopenharmony_ci pa_hook_slot *default_source_changed_slot; 11553a5a1b3Sopenharmony_ci pa_hook_slot *sample_cache_new_slot; 11653a5a1b3Sopenharmony_ci pa_hook_slot *sample_cache_removed_slot; 11753a5a1b3Sopenharmony_ci pa_hook_slot *card_put_slot; 11853a5a1b3Sopenharmony_ci pa_hook_slot *card_unlink_slot; 11953a5a1b3Sopenharmony_ci pa_hook_slot *sink_input_put_slot; 12053a5a1b3Sopenharmony_ci pa_hook_slot *sink_input_unlink_slot; 12153a5a1b3Sopenharmony_ci pa_hook_slot *source_output_put_slot; 12253a5a1b3Sopenharmony_ci pa_hook_slot *source_output_unlink_slot; 12353a5a1b3Sopenharmony_ci pa_hook_slot *client_put_slot; 12453a5a1b3Sopenharmony_ci pa_hook_slot *client_unlink_slot; 12553a5a1b3Sopenharmony_ci pa_hook_slot *sink_put_slot; 12653a5a1b3Sopenharmony_ci pa_hook_slot *sink_unlink_slot; 12753a5a1b3Sopenharmony_ci pa_hook_slot *source_put_slot; 12853a5a1b3Sopenharmony_ci pa_hook_slot *source_unlink_slot; 12953a5a1b3Sopenharmony_ci pa_hook_slot *extension_registered_slot; 13053a5a1b3Sopenharmony_ci pa_hook_slot *extension_unregistered_slot; 13153a5a1b3Sopenharmony_ci 13253a5a1b3Sopenharmony_ci pa_dbusiface_memstats *memstats; 13353a5a1b3Sopenharmony_ci}; 13453a5a1b3Sopenharmony_ci 13553a5a1b3Sopenharmony_cienum property_handler_index { 13653a5a1b3Sopenharmony_ci PROPERTY_HANDLER_INTERFACE_REVISION, 13753a5a1b3Sopenharmony_ci PROPERTY_HANDLER_NAME, 13853a5a1b3Sopenharmony_ci PROPERTY_HANDLER_VERSION, 13953a5a1b3Sopenharmony_ci PROPERTY_HANDLER_IS_LOCAL, 14053a5a1b3Sopenharmony_ci PROPERTY_HANDLER_USERNAME, 14153a5a1b3Sopenharmony_ci PROPERTY_HANDLER_HOSTNAME, 14253a5a1b3Sopenharmony_ci PROPERTY_HANDLER_DEFAULT_CHANNELS, 14353a5a1b3Sopenharmony_ci PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT, 14453a5a1b3Sopenharmony_ci PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE, 14553a5a1b3Sopenharmony_ci PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE, 14653a5a1b3Sopenharmony_ci PROPERTY_HANDLER_CARDS, 14753a5a1b3Sopenharmony_ci PROPERTY_HANDLER_SINKS, 14853a5a1b3Sopenharmony_ci PROPERTY_HANDLER_FALLBACK_SINK, 14953a5a1b3Sopenharmony_ci PROPERTY_HANDLER_SOURCES, 15053a5a1b3Sopenharmony_ci PROPERTY_HANDLER_FALLBACK_SOURCE, 15153a5a1b3Sopenharmony_ci PROPERTY_HANDLER_PLAYBACK_STREAMS, 15253a5a1b3Sopenharmony_ci PROPERTY_HANDLER_RECORD_STREAMS, 15353a5a1b3Sopenharmony_ci PROPERTY_HANDLER_SAMPLES, 15453a5a1b3Sopenharmony_ci PROPERTY_HANDLER_MODULES, 15553a5a1b3Sopenharmony_ci PROPERTY_HANDLER_CLIENTS, 15653a5a1b3Sopenharmony_ci PROPERTY_HANDLER_MY_CLIENT, 15753a5a1b3Sopenharmony_ci PROPERTY_HANDLER_EXTENSIONS, 15853a5a1b3Sopenharmony_ci PROPERTY_HANDLER_MAX 15953a5a1b3Sopenharmony_ci}; 16053a5a1b3Sopenharmony_ci 16153a5a1b3Sopenharmony_cistatic pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = { 16253a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_INTERFACE_REVISION] = { .property_name = "InterfaceRevision", .type = "u", .get_cb = handle_get_interface_revision, .set_cb = NULL }, 16353a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_NAME] = { .property_name = "Name", .type = "s", .get_cb = handle_get_name, .set_cb = NULL }, 16453a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_VERSION] = { .property_name = "Version", .type = "s", .get_cb = handle_get_version, .set_cb = NULL }, 16553a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_IS_LOCAL] = { .property_name = "IsLocal", .type = "b", .get_cb = handle_get_is_local, .set_cb = NULL }, 16653a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_USERNAME] = { .property_name = "Username", .type = "s", .get_cb = handle_get_username, .set_cb = NULL }, 16753a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_HOSTNAME] = { .property_name = "Hostname", .type = "s", .get_cb = handle_get_hostname, .set_cb = NULL }, 16853a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_DEFAULT_CHANNELS] = { .property_name = "DefaultChannels", .type = "au", .get_cb = handle_get_default_channels, .set_cb = handle_set_default_channels }, 16953a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT] = { .property_name = "DefaultSampleFormat", .type = "u", .get_cb = handle_get_default_sample_format, .set_cb = handle_set_default_sample_format }, 17053a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE] = { .property_name = "DefaultSampleRate", .type = "u", .get_cb = handle_get_default_sample_rate, .set_cb = handle_set_default_sample_rate }, 17153a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE] = { .property_name = "AlternateSampleRate", .type = "u", .get_cb = handle_get_alternate_sample_rate, .set_cb = handle_set_alternate_sample_rate }, 17253a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_CARDS] = { .property_name = "Cards", .type = "ao", .get_cb = handle_get_cards, .set_cb = NULL }, 17353a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_SINKS] = { .property_name = "Sinks", .type = "ao", .get_cb = handle_get_sinks, .set_cb = NULL }, 17453a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_FALLBACK_SINK] = { .property_name = "FallbackSink", .type = "o", .get_cb = handle_get_fallback_sink, .set_cb = handle_set_fallback_sink }, 17553a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_SOURCES] = { .property_name = "Sources", .type = "ao", .get_cb = handle_get_sources, .set_cb = NULL }, 17653a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_FALLBACK_SOURCE] = { .property_name = "FallbackSource", .type = "o", .get_cb = handle_get_fallback_source, .set_cb = handle_set_fallback_source }, 17753a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_PLAYBACK_STREAMS] = { .property_name = "PlaybackStreams", .type = "ao", .get_cb = handle_get_playback_streams, .set_cb = NULL }, 17853a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_RECORD_STREAMS] = { .property_name = "RecordStreams", .type = "ao", .get_cb = handle_get_record_streams, .set_cb = NULL }, 17953a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_SAMPLES] = { .property_name = "Samples", .type = "ao", .get_cb = handle_get_samples, .set_cb = NULL }, 18053a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_MODULES] = { .property_name = "Modules", .type = "ao", .get_cb = handle_get_modules, .set_cb = NULL }, 18153a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_CLIENTS] = { .property_name = "Clients", .type = "ao", .get_cb = handle_get_clients, .set_cb = NULL }, 18253a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_MY_CLIENT] = { .property_name = "MyClient", .type = "o", .get_cb = handle_get_my_client, .set_cb = NULL }, 18353a5a1b3Sopenharmony_ci [PROPERTY_HANDLER_EXTENSIONS] = { .property_name = "Extensions", .type = "as", .get_cb = handle_get_extensions, .set_cb = NULL } 18453a5a1b3Sopenharmony_ci}; 18553a5a1b3Sopenharmony_ci 18653a5a1b3Sopenharmony_cienum method_handler_index { 18753a5a1b3Sopenharmony_ci METHOD_HANDLER_GET_CARD_BY_NAME, 18853a5a1b3Sopenharmony_ci METHOD_HANDLER_GET_SINK_BY_NAME, 18953a5a1b3Sopenharmony_ci METHOD_HANDLER_GET_SOURCE_BY_NAME, 19053a5a1b3Sopenharmony_ci METHOD_HANDLER_GET_SAMPLE_BY_NAME, 19153a5a1b3Sopenharmony_ci METHOD_HANDLER_UPLOAD_SAMPLE, 19253a5a1b3Sopenharmony_ci METHOD_HANDLER_LOAD_MODULE, 19353a5a1b3Sopenharmony_ci METHOD_HANDLER_EXIT, 19453a5a1b3Sopenharmony_ci METHOD_HANDLER_LISTEN_FOR_SIGNAL, 19553a5a1b3Sopenharmony_ci METHOD_HANDLER_STOP_LISTENING_FOR_SIGNAL, 19653a5a1b3Sopenharmony_ci METHOD_HANDLER_MAX 19753a5a1b3Sopenharmony_ci}; 19853a5a1b3Sopenharmony_ci 19953a5a1b3Sopenharmony_cistatic pa_dbus_arg_info get_card_by_name_args[] = { { "name", "s", "in" }, { "card", "o", "out" } }; 20053a5a1b3Sopenharmony_cistatic pa_dbus_arg_info get_sink_by_name_args[] = { { "name", "s", "in" }, { "sink", "o", "out" } }; 20153a5a1b3Sopenharmony_cistatic pa_dbus_arg_info get_source_by_name_args[] = { { "name", "s", "in" }, { "source", "o", "out" } }; 20253a5a1b3Sopenharmony_cistatic pa_dbus_arg_info get_sample_by_name_args[] = { { "name", "s", "in" }, { "sample", "o", "out" } }; 20353a5a1b3Sopenharmony_cistatic pa_dbus_arg_info upload_sample_args[] = { { "name", "s", "in" }, 20453a5a1b3Sopenharmony_ci { "sample_format", "u", "in" }, 20553a5a1b3Sopenharmony_ci { "sample_rate", "u", "in" }, 20653a5a1b3Sopenharmony_ci { "channels", "au", "in" }, 20753a5a1b3Sopenharmony_ci { "default_volume", "au", "in" }, 20853a5a1b3Sopenharmony_ci { "property_list", "a{say}", "in" }, 20953a5a1b3Sopenharmony_ci { "data", "ay", "in" }, 21053a5a1b3Sopenharmony_ci { "sample", "o", "out" } }; 21153a5a1b3Sopenharmony_cistatic pa_dbus_arg_info load_module_args[] = { { "name", "s", "in" }, { "arguments", "a{ss}", "in" }, { "module", "o", "out" } }; 21253a5a1b3Sopenharmony_cistatic pa_dbus_arg_info listen_for_signal_args[] = { { "signal", "s", "in" }, { "objects", "ao", "in" } }; 21353a5a1b3Sopenharmony_cistatic pa_dbus_arg_info stop_listening_for_signal_args[] = { { "signal", "s", "in" } }; 21453a5a1b3Sopenharmony_ci 21553a5a1b3Sopenharmony_cistatic pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { 21653a5a1b3Sopenharmony_ci [METHOD_HANDLER_GET_CARD_BY_NAME] = { 21753a5a1b3Sopenharmony_ci .method_name = "GetCardByName", 21853a5a1b3Sopenharmony_ci .arguments = get_card_by_name_args, 21953a5a1b3Sopenharmony_ci .n_arguments = sizeof(get_card_by_name_args) / sizeof(pa_dbus_arg_info), 22053a5a1b3Sopenharmony_ci .receive_cb = handle_get_card_by_name }, 22153a5a1b3Sopenharmony_ci [METHOD_HANDLER_GET_SINK_BY_NAME] = { 22253a5a1b3Sopenharmony_ci .method_name = "GetSinkByName", 22353a5a1b3Sopenharmony_ci .arguments = get_sink_by_name_args, 22453a5a1b3Sopenharmony_ci .n_arguments = sizeof(get_sink_by_name_args) / sizeof(pa_dbus_arg_info), 22553a5a1b3Sopenharmony_ci .receive_cb = handle_get_sink_by_name }, 22653a5a1b3Sopenharmony_ci [METHOD_HANDLER_GET_SOURCE_BY_NAME] = { 22753a5a1b3Sopenharmony_ci .method_name = "GetSourceByName", 22853a5a1b3Sopenharmony_ci .arguments = get_source_by_name_args, 22953a5a1b3Sopenharmony_ci .n_arguments = sizeof(get_source_by_name_args) / sizeof(pa_dbus_arg_info), 23053a5a1b3Sopenharmony_ci .receive_cb = handle_get_source_by_name }, 23153a5a1b3Sopenharmony_ci [METHOD_HANDLER_GET_SAMPLE_BY_NAME] = { 23253a5a1b3Sopenharmony_ci .method_name = "GetSampleByName", 23353a5a1b3Sopenharmony_ci .arguments = get_sample_by_name_args, 23453a5a1b3Sopenharmony_ci .n_arguments = sizeof(get_sample_by_name_args) / sizeof(pa_dbus_arg_info), 23553a5a1b3Sopenharmony_ci .receive_cb = handle_get_sample_by_name }, 23653a5a1b3Sopenharmony_ci [METHOD_HANDLER_UPLOAD_SAMPLE] = { 23753a5a1b3Sopenharmony_ci .method_name = "UploadSample", 23853a5a1b3Sopenharmony_ci .arguments = upload_sample_args, 23953a5a1b3Sopenharmony_ci .n_arguments = sizeof(upload_sample_args) / sizeof(pa_dbus_arg_info), 24053a5a1b3Sopenharmony_ci .receive_cb = handle_upload_sample }, 24153a5a1b3Sopenharmony_ci [METHOD_HANDLER_LOAD_MODULE] = { 24253a5a1b3Sopenharmony_ci .method_name = "LoadModule", 24353a5a1b3Sopenharmony_ci .arguments = load_module_args, 24453a5a1b3Sopenharmony_ci .n_arguments = sizeof(load_module_args) / sizeof(pa_dbus_arg_info), 24553a5a1b3Sopenharmony_ci .receive_cb = handle_load_module }, 24653a5a1b3Sopenharmony_ci [METHOD_HANDLER_EXIT] = { 24753a5a1b3Sopenharmony_ci .method_name = "Exit", 24853a5a1b3Sopenharmony_ci .arguments = NULL, 24953a5a1b3Sopenharmony_ci .n_arguments = 0, 25053a5a1b3Sopenharmony_ci .receive_cb = handle_exit }, 25153a5a1b3Sopenharmony_ci [METHOD_HANDLER_LISTEN_FOR_SIGNAL] = { 25253a5a1b3Sopenharmony_ci .method_name = "ListenForSignal", 25353a5a1b3Sopenharmony_ci .arguments = listen_for_signal_args, 25453a5a1b3Sopenharmony_ci .n_arguments = sizeof(listen_for_signal_args) / sizeof(pa_dbus_arg_info), 25553a5a1b3Sopenharmony_ci .receive_cb = handle_listen_for_signal }, 25653a5a1b3Sopenharmony_ci [METHOD_HANDLER_STOP_LISTENING_FOR_SIGNAL] = { 25753a5a1b3Sopenharmony_ci .method_name = "StopListeningForSignal", 25853a5a1b3Sopenharmony_ci .arguments = stop_listening_for_signal_args, 25953a5a1b3Sopenharmony_ci .n_arguments = sizeof(stop_listening_for_signal_args) / sizeof(pa_dbus_arg_info), 26053a5a1b3Sopenharmony_ci .receive_cb = handle_stop_listening_for_signal } 26153a5a1b3Sopenharmony_ci}; 26253a5a1b3Sopenharmony_ci 26353a5a1b3Sopenharmony_cienum signal_index { 26453a5a1b3Sopenharmony_ci SIGNAL_NEW_CARD, 26553a5a1b3Sopenharmony_ci SIGNAL_CARD_REMOVED, 26653a5a1b3Sopenharmony_ci SIGNAL_NEW_SINK, 26753a5a1b3Sopenharmony_ci SIGNAL_SINK_REMOVED, 26853a5a1b3Sopenharmony_ci SIGNAL_FALLBACK_SINK_UPDATED, 26953a5a1b3Sopenharmony_ci SIGNAL_FALLBACK_SINK_UNSET, 27053a5a1b3Sopenharmony_ci SIGNAL_NEW_SOURCE, 27153a5a1b3Sopenharmony_ci SIGNAL_SOURCE_REMOVED, 27253a5a1b3Sopenharmony_ci SIGNAL_FALLBACK_SOURCE_UPDATED, 27353a5a1b3Sopenharmony_ci SIGNAL_FALLBACK_SOURCE_UNSET, 27453a5a1b3Sopenharmony_ci SIGNAL_NEW_PLAYBACK_STREAM, 27553a5a1b3Sopenharmony_ci SIGNAL_PLAYBACK_STREAM_REMOVED, 27653a5a1b3Sopenharmony_ci SIGNAL_NEW_RECORD_STREAM, 27753a5a1b3Sopenharmony_ci SIGNAL_RECORD_STREAM_REMOVED, 27853a5a1b3Sopenharmony_ci SIGNAL_NEW_SAMPLE, 27953a5a1b3Sopenharmony_ci SIGNAL_SAMPLE_REMOVED, 28053a5a1b3Sopenharmony_ci SIGNAL_NEW_MODULE, 28153a5a1b3Sopenharmony_ci SIGNAL_MODULE_REMOVED, 28253a5a1b3Sopenharmony_ci SIGNAL_NEW_CLIENT, 28353a5a1b3Sopenharmony_ci SIGNAL_CLIENT_REMOVED, 28453a5a1b3Sopenharmony_ci SIGNAL_NEW_EXTENSION, 28553a5a1b3Sopenharmony_ci SIGNAL_EXTENSION_REMOVED, 28653a5a1b3Sopenharmony_ci SIGNAL_MAX 28753a5a1b3Sopenharmony_ci}; 28853a5a1b3Sopenharmony_ci 28953a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_card_args[] = { { "card", "o", NULL } }; 29053a5a1b3Sopenharmony_cistatic pa_dbus_arg_info card_removed_args[] = { { "card", "o", NULL } }; 29153a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_sink_args[] = { { "sink", "o", NULL } }; 29253a5a1b3Sopenharmony_cistatic pa_dbus_arg_info sink_removed_args[] = { { "sink", "o", NULL } }; 29353a5a1b3Sopenharmony_cistatic pa_dbus_arg_info fallback_sink_updated_args[] = { { "sink", "o", NULL } }; 29453a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_source_args[] = { { "source", "o", NULL } }; 29553a5a1b3Sopenharmony_cistatic pa_dbus_arg_info source_removed_args[] = { { "source", "o", NULL } }; 29653a5a1b3Sopenharmony_cistatic pa_dbus_arg_info fallback_source_updated_args[] = { { "source", "o", NULL } }; 29753a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_playback_stream_args[] = { { "playback_stream", "o", NULL } }; 29853a5a1b3Sopenharmony_cistatic pa_dbus_arg_info playback_stream_removed_args[] = { { "playback_stream", "o", NULL } }; 29953a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_record_stream_args[] = { { "record_stream", "o", NULL } }; 30053a5a1b3Sopenharmony_cistatic pa_dbus_arg_info record_stream_removed_args[] = { { "record_stream", "o", NULL } }; 30153a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_sample_args[] = { { "sample", "o", NULL } }; 30253a5a1b3Sopenharmony_cistatic pa_dbus_arg_info sample_removed_args[] = { { "sample", "o", NULL } }; 30353a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_module_args[] = { { "module", "o", NULL } }; 30453a5a1b3Sopenharmony_cistatic pa_dbus_arg_info module_removed_args[] = { { "module", "o", NULL } }; 30553a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_client_args[] = { { "client", "o", NULL } }; 30653a5a1b3Sopenharmony_cistatic pa_dbus_arg_info client_removed_args[] = { { "client", "o", NULL } }; 30753a5a1b3Sopenharmony_cistatic pa_dbus_arg_info new_extension_args[] = { { "extension", "s", NULL } }; 30853a5a1b3Sopenharmony_cistatic pa_dbus_arg_info extension_removed_args[] = { { "extension", "s", NULL } }; 30953a5a1b3Sopenharmony_ci 31053a5a1b3Sopenharmony_cistatic pa_dbus_signal_info signals[SIGNAL_MAX] = { 31153a5a1b3Sopenharmony_ci [SIGNAL_NEW_CARD] = { .name = "NewCard", .arguments = new_card_args, .n_arguments = 1 }, 31253a5a1b3Sopenharmony_ci [SIGNAL_CARD_REMOVED] = { .name = "CardRemoved", .arguments = card_removed_args, .n_arguments = 1 }, 31353a5a1b3Sopenharmony_ci [SIGNAL_NEW_SINK] = { .name = "NewSink", .arguments = new_sink_args, .n_arguments = 1 }, 31453a5a1b3Sopenharmony_ci [SIGNAL_SINK_REMOVED] = { .name = "SinkRemoved", .arguments = sink_removed_args, .n_arguments = 1 }, 31553a5a1b3Sopenharmony_ci [SIGNAL_FALLBACK_SINK_UPDATED] = { .name = "FallbackSinkUpdated", .arguments = fallback_sink_updated_args, .n_arguments = 1 }, 31653a5a1b3Sopenharmony_ci [SIGNAL_FALLBACK_SINK_UNSET] = { .name = "FallbackSinkUnset", .arguments = NULL, .n_arguments = 0 }, 31753a5a1b3Sopenharmony_ci [SIGNAL_NEW_SOURCE] = { .name = "NewSource", .arguments = new_source_args, .n_arguments = 1 }, 31853a5a1b3Sopenharmony_ci [SIGNAL_SOURCE_REMOVED] = { .name = "SourceRemoved", .arguments = source_removed_args, .n_arguments = 1 }, 31953a5a1b3Sopenharmony_ci [SIGNAL_FALLBACK_SOURCE_UPDATED] = { .name = "FallbackSourceUpdated", .arguments = fallback_source_updated_args, .n_arguments = 1 }, 32053a5a1b3Sopenharmony_ci [SIGNAL_FALLBACK_SOURCE_UNSET] = { .name = "FallbackSourceUnset", .arguments = NULL, .n_arguments = 0 }, 32153a5a1b3Sopenharmony_ci [SIGNAL_NEW_PLAYBACK_STREAM] = { .name = "NewPlaybackStream", .arguments = new_playback_stream_args, .n_arguments = 1 }, 32253a5a1b3Sopenharmony_ci [SIGNAL_PLAYBACK_STREAM_REMOVED] = { .name = "PlaybackStreamRemoved", .arguments = playback_stream_removed_args, .n_arguments = 1 }, 32353a5a1b3Sopenharmony_ci [SIGNAL_NEW_RECORD_STREAM] = { .name = "NewRecordStream", .arguments = new_record_stream_args, .n_arguments = 1 }, 32453a5a1b3Sopenharmony_ci [SIGNAL_RECORD_STREAM_REMOVED] = { .name = "RecordStreamRemoved", .arguments = record_stream_removed_args, .n_arguments = 1 }, 32553a5a1b3Sopenharmony_ci [SIGNAL_NEW_SAMPLE] = { .name = "NewSample", .arguments = new_sample_args, .n_arguments = 1 }, 32653a5a1b3Sopenharmony_ci [SIGNAL_SAMPLE_REMOVED] = { .name = "SampleRemoved", .arguments = sample_removed_args, .n_arguments = 1 }, 32753a5a1b3Sopenharmony_ci [SIGNAL_NEW_MODULE] = { .name = "NewModule", .arguments = new_module_args, .n_arguments = 1 }, 32853a5a1b3Sopenharmony_ci [SIGNAL_MODULE_REMOVED] = { .name = "ModuleRemoved", .arguments = module_removed_args, .n_arguments = 1 }, 32953a5a1b3Sopenharmony_ci [SIGNAL_NEW_CLIENT] = { .name = "NewClient", .arguments = new_client_args, .n_arguments = 1 }, 33053a5a1b3Sopenharmony_ci [SIGNAL_CLIENT_REMOVED] = { .name = "ClientRemoved", .arguments = client_removed_args, .n_arguments = 1 }, 33153a5a1b3Sopenharmony_ci [SIGNAL_NEW_EXTENSION] = { .name = "NewExtension", .arguments = new_extension_args, .n_arguments = 1 }, 33253a5a1b3Sopenharmony_ci [SIGNAL_EXTENSION_REMOVED] = { .name = "ExtensionRemoved", .arguments = extension_removed_args, .n_arguments = 1 } 33353a5a1b3Sopenharmony_ci}; 33453a5a1b3Sopenharmony_ci 33553a5a1b3Sopenharmony_cistatic pa_dbus_interface_info core_interface_info = { 33653a5a1b3Sopenharmony_ci .name = PA_DBUS_CORE_INTERFACE, 33753a5a1b3Sopenharmony_ci .method_handlers = method_handlers, 33853a5a1b3Sopenharmony_ci .n_method_handlers = METHOD_HANDLER_MAX, 33953a5a1b3Sopenharmony_ci .property_handlers = property_handlers, 34053a5a1b3Sopenharmony_ci .n_property_handlers = PROPERTY_HANDLER_MAX, 34153a5a1b3Sopenharmony_ci .get_all_properties_cb = handle_get_all, 34253a5a1b3Sopenharmony_ci .signals = signals, 34353a5a1b3Sopenharmony_ci .n_signals = SIGNAL_MAX 34453a5a1b3Sopenharmony_ci}; 34553a5a1b3Sopenharmony_ci 34653a5a1b3Sopenharmony_cistatic void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata) { 34753a5a1b3Sopenharmony_ci dbus_uint32_t interface_revision = INTERFACE_REVISION; 34853a5a1b3Sopenharmony_ci 34953a5a1b3Sopenharmony_ci pa_assert(conn); 35053a5a1b3Sopenharmony_ci pa_assert(msg); 35153a5a1b3Sopenharmony_ci 35253a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &interface_revision); 35353a5a1b3Sopenharmony_ci} 35453a5a1b3Sopenharmony_ci 35553a5a1b3Sopenharmony_cistatic void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { 35653a5a1b3Sopenharmony_ci const char *server_name = PACKAGE_NAME; 35753a5a1b3Sopenharmony_ci 35853a5a1b3Sopenharmony_ci pa_assert(conn); 35953a5a1b3Sopenharmony_ci pa_assert(msg); 36053a5a1b3Sopenharmony_ci 36153a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &server_name); 36253a5a1b3Sopenharmony_ci} 36353a5a1b3Sopenharmony_ci 36453a5a1b3Sopenharmony_cistatic void handle_get_version(DBusConnection *conn, DBusMessage *msg, void *userdata) { 36553a5a1b3Sopenharmony_ci const char *version = PACKAGE_VERSION; 36653a5a1b3Sopenharmony_ci 36753a5a1b3Sopenharmony_ci pa_assert(conn); 36853a5a1b3Sopenharmony_ci pa_assert(msg); 36953a5a1b3Sopenharmony_ci 37053a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &version); 37153a5a1b3Sopenharmony_ci} 37253a5a1b3Sopenharmony_ci 37353a5a1b3Sopenharmony_cistatic dbus_bool_t get_is_local(DBusConnection *conn) { 37453a5a1b3Sopenharmony_ci int conn_fd; 37553a5a1b3Sopenharmony_ci 37653a5a1b3Sopenharmony_ci pa_assert(conn); 37753a5a1b3Sopenharmony_ci 37853a5a1b3Sopenharmony_ci if (!dbus_connection_get_socket(conn, &conn_fd)) 37953a5a1b3Sopenharmony_ci return FALSE; 38053a5a1b3Sopenharmony_ci 38153a5a1b3Sopenharmony_ci return pa_socket_is_local(conn_fd); 38253a5a1b3Sopenharmony_ci} 38353a5a1b3Sopenharmony_ci 38453a5a1b3Sopenharmony_cistatic void handle_get_is_local(DBusConnection *conn, DBusMessage *msg, void *userdata) { 38553a5a1b3Sopenharmony_ci dbus_bool_t is_local; 38653a5a1b3Sopenharmony_ci 38753a5a1b3Sopenharmony_ci pa_assert(conn); 38853a5a1b3Sopenharmony_ci pa_assert(msg); 38953a5a1b3Sopenharmony_ci 39053a5a1b3Sopenharmony_ci is_local = get_is_local(conn); 39153a5a1b3Sopenharmony_ci 39253a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &is_local); 39353a5a1b3Sopenharmony_ci} 39453a5a1b3Sopenharmony_ci 39553a5a1b3Sopenharmony_cistatic void handle_get_username(DBusConnection *conn, DBusMessage *msg, void *userdata) { 39653a5a1b3Sopenharmony_ci char *username = NULL; 39753a5a1b3Sopenharmony_ci 39853a5a1b3Sopenharmony_ci pa_assert(conn); 39953a5a1b3Sopenharmony_ci pa_assert(msg); 40053a5a1b3Sopenharmony_ci 40153a5a1b3Sopenharmony_ci username = pa_get_user_name_malloc(); 40253a5a1b3Sopenharmony_ci 40353a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &username); 40453a5a1b3Sopenharmony_ci 40553a5a1b3Sopenharmony_ci pa_xfree(username); 40653a5a1b3Sopenharmony_ci} 40753a5a1b3Sopenharmony_ci 40853a5a1b3Sopenharmony_cistatic void handle_get_hostname(DBusConnection *conn, DBusMessage *msg, void *userdata) { 40953a5a1b3Sopenharmony_ci char *hostname = NULL; 41053a5a1b3Sopenharmony_ci 41153a5a1b3Sopenharmony_ci pa_assert(conn); 41253a5a1b3Sopenharmony_ci pa_assert(msg); 41353a5a1b3Sopenharmony_ci 41453a5a1b3Sopenharmony_ci hostname = pa_get_host_name_malloc(); 41553a5a1b3Sopenharmony_ci 41653a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &hostname); 41753a5a1b3Sopenharmony_ci 41853a5a1b3Sopenharmony_ci pa_xfree(hostname); 41953a5a1b3Sopenharmony_ci} 42053a5a1b3Sopenharmony_ci 42153a5a1b3Sopenharmony_ci/* Caller frees the returned array. */ 42253a5a1b3Sopenharmony_cistatic dbus_uint32_t *get_default_channels(pa_dbusiface_core *c, unsigned *n) { 42353a5a1b3Sopenharmony_ci dbus_uint32_t *default_channels = NULL; 42453a5a1b3Sopenharmony_ci unsigned i; 42553a5a1b3Sopenharmony_ci 42653a5a1b3Sopenharmony_ci pa_assert(c); 42753a5a1b3Sopenharmony_ci pa_assert(n); 42853a5a1b3Sopenharmony_ci 42953a5a1b3Sopenharmony_ci *n = c->core->default_channel_map.channels; 43053a5a1b3Sopenharmony_ci default_channels = pa_xnew(dbus_uint32_t, *n); 43153a5a1b3Sopenharmony_ci 43253a5a1b3Sopenharmony_ci for (i = 0; i < *n; ++i) 43353a5a1b3Sopenharmony_ci default_channels[i] = c->core->default_channel_map.map[i]; 43453a5a1b3Sopenharmony_ci 43553a5a1b3Sopenharmony_ci return default_channels; 43653a5a1b3Sopenharmony_ci} 43753a5a1b3Sopenharmony_ci 43853a5a1b3Sopenharmony_cistatic void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) { 43953a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 44053a5a1b3Sopenharmony_ci dbus_uint32_t *default_channels = NULL; 44153a5a1b3Sopenharmony_ci unsigned n; 44253a5a1b3Sopenharmony_ci 44353a5a1b3Sopenharmony_ci pa_assert(conn); 44453a5a1b3Sopenharmony_ci pa_assert(msg); 44553a5a1b3Sopenharmony_ci pa_assert(c); 44653a5a1b3Sopenharmony_ci 44753a5a1b3Sopenharmony_ci default_channels = get_default_channels(c, &n); 44853a5a1b3Sopenharmony_ci 44953a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, default_channels, n); 45053a5a1b3Sopenharmony_ci 45153a5a1b3Sopenharmony_ci pa_xfree(default_channels); 45253a5a1b3Sopenharmony_ci} 45353a5a1b3Sopenharmony_ci 45453a5a1b3Sopenharmony_cistatic void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { 45553a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 45653a5a1b3Sopenharmony_ci DBusMessageIter array_iter; 45753a5a1b3Sopenharmony_ci pa_channel_map new_channel_map; 45853a5a1b3Sopenharmony_ci const dbus_uint32_t *default_channels; 45953a5a1b3Sopenharmony_ci int n_channels; 46053a5a1b3Sopenharmony_ci unsigned i; 46153a5a1b3Sopenharmony_ci 46253a5a1b3Sopenharmony_ci pa_assert(conn); 46353a5a1b3Sopenharmony_ci pa_assert(msg); 46453a5a1b3Sopenharmony_ci pa_assert(iter); 46553a5a1b3Sopenharmony_ci pa_assert(c); 46653a5a1b3Sopenharmony_ci 46753a5a1b3Sopenharmony_ci pa_channel_map_init(&new_channel_map); 46853a5a1b3Sopenharmony_ci 46953a5a1b3Sopenharmony_ci dbus_message_iter_recurse(iter, &array_iter); 47053a5a1b3Sopenharmony_ci dbus_message_iter_get_fixed_array(&array_iter, &default_channels, &n_channels); 47153a5a1b3Sopenharmony_ci 47253a5a1b3Sopenharmony_ci if (n_channels <= 0) { 47353a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel array."); 47453a5a1b3Sopenharmony_ci return; 47553a5a1b3Sopenharmony_ci } 47653a5a1b3Sopenharmony_ci 47753a5a1b3Sopenharmony_ci if (n_channels > (int) PA_CHANNELS_MAX) { 47853a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, 47953a5a1b3Sopenharmony_ci "Too many channels: %i. The maximum number of channels is %u.", n_channels, PA_CHANNELS_MAX); 48053a5a1b3Sopenharmony_ci return; 48153a5a1b3Sopenharmony_ci } 48253a5a1b3Sopenharmony_ci 48353a5a1b3Sopenharmony_ci new_channel_map.channels = n_channels; 48453a5a1b3Sopenharmony_ci 48553a5a1b3Sopenharmony_ci for (i = 0; i < new_channel_map.channels; ++i) { 48653a5a1b3Sopenharmony_ci if (default_channels[i] >= PA_CHANNEL_POSITION_MAX) { 48753a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position: %u.", default_channels[i]); 48853a5a1b3Sopenharmony_ci return; 48953a5a1b3Sopenharmony_ci } 49053a5a1b3Sopenharmony_ci 49153a5a1b3Sopenharmony_ci new_channel_map.map[i] = default_channels[i]; 49253a5a1b3Sopenharmony_ci } 49353a5a1b3Sopenharmony_ci 49453a5a1b3Sopenharmony_ci c->core->default_channel_map = new_channel_map; 49553a5a1b3Sopenharmony_ci c->core->default_sample_spec.channels = n_channels; 49653a5a1b3Sopenharmony_ci 49753a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 49853a5a1b3Sopenharmony_ci} 49953a5a1b3Sopenharmony_ci 50053a5a1b3Sopenharmony_cistatic void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) { 50153a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 50253a5a1b3Sopenharmony_ci dbus_uint32_t default_sample_format; 50353a5a1b3Sopenharmony_ci 50453a5a1b3Sopenharmony_ci pa_assert(conn); 50553a5a1b3Sopenharmony_ci pa_assert(msg); 50653a5a1b3Sopenharmony_ci pa_assert(c); 50753a5a1b3Sopenharmony_ci 50853a5a1b3Sopenharmony_ci default_sample_format = c->core->default_sample_spec.format; 50953a5a1b3Sopenharmony_ci 51053a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &default_sample_format); 51153a5a1b3Sopenharmony_ci} 51253a5a1b3Sopenharmony_ci 51353a5a1b3Sopenharmony_cistatic void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { 51453a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 51553a5a1b3Sopenharmony_ci dbus_uint32_t default_sample_format; 51653a5a1b3Sopenharmony_ci 51753a5a1b3Sopenharmony_ci pa_assert(conn); 51853a5a1b3Sopenharmony_ci pa_assert(msg); 51953a5a1b3Sopenharmony_ci pa_assert(iter); 52053a5a1b3Sopenharmony_ci pa_assert(c); 52153a5a1b3Sopenharmony_ci 52253a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(iter, &default_sample_format); 52353a5a1b3Sopenharmony_ci 52453a5a1b3Sopenharmony_ci if (!pa_sample_format_valid(default_sample_format)) { 52553a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format."); 52653a5a1b3Sopenharmony_ci return; 52753a5a1b3Sopenharmony_ci } 52853a5a1b3Sopenharmony_ci 52953a5a1b3Sopenharmony_ci c->core->default_sample_spec.format = default_sample_format; 53053a5a1b3Sopenharmony_ci 53153a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 53253a5a1b3Sopenharmony_ci} 53353a5a1b3Sopenharmony_ci 53453a5a1b3Sopenharmony_cistatic void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { 53553a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 53653a5a1b3Sopenharmony_ci dbus_uint32_t default_sample_rate; 53753a5a1b3Sopenharmony_ci 53853a5a1b3Sopenharmony_ci pa_assert(conn); 53953a5a1b3Sopenharmony_ci pa_assert(msg); 54053a5a1b3Sopenharmony_ci pa_assert(c); 54153a5a1b3Sopenharmony_ci 54253a5a1b3Sopenharmony_ci default_sample_rate = c->core->default_sample_spec.rate; 54353a5a1b3Sopenharmony_ci 54453a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &default_sample_rate); 54553a5a1b3Sopenharmony_ci} 54653a5a1b3Sopenharmony_ci 54753a5a1b3Sopenharmony_cistatic void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { 54853a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 54953a5a1b3Sopenharmony_ci dbus_uint32_t default_sample_rate; 55053a5a1b3Sopenharmony_ci 55153a5a1b3Sopenharmony_ci pa_assert(conn); 55253a5a1b3Sopenharmony_ci pa_assert(msg); 55353a5a1b3Sopenharmony_ci pa_assert(iter); 55453a5a1b3Sopenharmony_ci pa_assert(c); 55553a5a1b3Sopenharmony_ci 55653a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(iter, &default_sample_rate); 55753a5a1b3Sopenharmony_ci 55853a5a1b3Sopenharmony_ci if (!pa_sample_rate_valid(default_sample_rate)) { 55953a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate."); 56053a5a1b3Sopenharmony_ci return; 56153a5a1b3Sopenharmony_ci } 56253a5a1b3Sopenharmony_ci 56353a5a1b3Sopenharmony_ci c->core->default_sample_spec.rate = default_sample_rate; 56453a5a1b3Sopenharmony_ci 56553a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 56653a5a1b3Sopenharmony_ci} 56753a5a1b3Sopenharmony_ci 56853a5a1b3Sopenharmony_cistatic void handle_get_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { 56953a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 57053a5a1b3Sopenharmony_ci dbus_uint32_t alternate_sample_rate; 57153a5a1b3Sopenharmony_ci 57253a5a1b3Sopenharmony_ci pa_assert(conn); 57353a5a1b3Sopenharmony_ci pa_assert(msg); 57453a5a1b3Sopenharmony_ci pa_assert(c); 57553a5a1b3Sopenharmony_ci 57653a5a1b3Sopenharmony_ci alternate_sample_rate = c->core->alternate_sample_rate; 57753a5a1b3Sopenharmony_ci 57853a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &alternate_sample_rate); 57953a5a1b3Sopenharmony_ci} 58053a5a1b3Sopenharmony_ci 58153a5a1b3Sopenharmony_cistatic void handle_set_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { 58253a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 58353a5a1b3Sopenharmony_ci dbus_uint32_t alternate_sample_rate; 58453a5a1b3Sopenharmony_ci 58553a5a1b3Sopenharmony_ci pa_assert(conn); 58653a5a1b3Sopenharmony_ci pa_assert(msg); 58753a5a1b3Sopenharmony_ci pa_assert(iter); 58853a5a1b3Sopenharmony_ci pa_assert(c); 58953a5a1b3Sopenharmony_ci 59053a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(iter, &alternate_sample_rate); 59153a5a1b3Sopenharmony_ci 59253a5a1b3Sopenharmony_ci if (!pa_sample_rate_valid(alternate_sample_rate)) { 59353a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate."); 59453a5a1b3Sopenharmony_ci return; 59553a5a1b3Sopenharmony_ci } 59653a5a1b3Sopenharmony_ci 59753a5a1b3Sopenharmony_ci c->core->alternate_sample_rate = alternate_sample_rate; 59853a5a1b3Sopenharmony_ci 59953a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 60053a5a1b3Sopenharmony_ci} 60153a5a1b3Sopenharmony_ci 60253a5a1b3Sopenharmony_ci/* The caller frees the array, but not the strings. */ 60353a5a1b3Sopenharmony_cistatic const char **get_cards(pa_dbusiface_core *c, unsigned *n) { 60453a5a1b3Sopenharmony_ci const char **cards; 60553a5a1b3Sopenharmony_ci unsigned i = 0; 60653a5a1b3Sopenharmony_ci void *state = NULL; 60753a5a1b3Sopenharmony_ci pa_dbusiface_card *card; 60853a5a1b3Sopenharmony_ci 60953a5a1b3Sopenharmony_ci pa_assert(c); 61053a5a1b3Sopenharmony_ci pa_assert(n); 61153a5a1b3Sopenharmony_ci 61253a5a1b3Sopenharmony_ci *n = pa_hashmap_size(c->cards); 61353a5a1b3Sopenharmony_ci 61453a5a1b3Sopenharmony_ci if (*n == 0) 61553a5a1b3Sopenharmony_ci return NULL; 61653a5a1b3Sopenharmony_ci 61753a5a1b3Sopenharmony_ci cards = pa_xnew(const char *, *n); 61853a5a1b3Sopenharmony_ci 61953a5a1b3Sopenharmony_ci PA_HASHMAP_FOREACH(card, c->cards, state) 62053a5a1b3Sopenharmony_ci cards[i++] = pa_dbusiface_card_get_path(card); 62153a5a1b3Sopenharmony_ci 62253a5a1b3Sopenharmony_ci return cards; 62353a5a1b3Sopenharmony_ci} 62453a5a1b3Sopenharmony_ci 62553a5a1b3Sopenharmony_cistatic void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userdata) { 62653a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 62753a5a1b3Sopenharmony_ci const char **cards; 62853a5a1b3Sopenharmony_ci unsigned n; 62953a5a1b3Sopenharmony_ci 63053a5a1b3Sopenharmony_ci pa_assert(conn); 63153a5a1b3Sopenharmony_ci pa_assert(msg); 63253a5a1b3Sopenharmony_ci pa_assert(c); 63353a5a1b3Sopenharmony_ci 63453a5a1b3Sopenharmony_ci cards = get_cards(c, &n); 63553a5a1b3Sopenharmony_ci 63653a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, cards, n); 63753a5a1b3Sopenharmony_ci 63853a5a1b3Sopenharmony_ci pa_xfree(cards); 63953a5a1b3Sopenharmony_ci} 64053a5a1b3Sopenharmony_ci 64153a5a1b3Sopenharmony_ci/* The caller frees the array, but not the strings. */ 64253a5a1b3Sopenharmony_cistatic const char **get_sinks(pa_dbusiface_core *c, unsigned *n) { 64353a5a1b3Sopenharmony_ci const char **sinks; 64453a5a1b3Sopenharmony_ci unsigned i = 0; 64553a5a1b3Sopenharmony_ci void *state = NULL; 64653a5a1b3Sopenharmony_ci pa_dbusiface_device *sink; 64753a5a1b3Sopenharmony_ci 64853a5a1b3Sopenharmony_ci pa_assert(c); 64953a5a1b3Sopenharmony_ci pa_assert(n); 65053a5a1b3Sopenharmony_ci 65153a5a1b3Sopenharmony_ci *n = pa_hashmap_size(c->sinks_by_index); 65253a5a1b3Sopenharmony_ci 65353a5a1b3Sopenharmony_ci if (*n == 0) 65453a5a1b3Sopenharmony_ci return NULL; 65553a5a1b3Sopenharmony_ci 65653a5a1b3Sopenharmony_ci sinks = pa_xnew(const char *, *n); 65753a5a1b3Sopenharmony_ci 65853a5a1b3Sopenharmony_ci PA_HASHMAP_FOREACH(sink, c->sinks_by_index, state) 65953a5a1b3Sopenharmony_ci sinks[i++] = pa_dbusiface_device_get_path(sink); 66053a5a1b3Sopenharmony_ci 66153a5a1b3Sopenharmony_ci return sinks; 66253a5a1b3Sopenharmony_ci} 66353a5a1b3Sopenharmony_ci 66453a5a1b3Sopenharmony_cistatic void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata) { 66553a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 66653a5a1b3Sopenharmony_ci const char **sinks; 66753a5a1b3Sopenharmony_ci unsigned n; 66853a5a1b3Sopenharmony_ci 66953a5a1b3Sopenharmony_ci pa_assert(conn); 67053a5a1b3Sopenharmony_ci pa_assert(msg); 67153a5a1b3Sopenharmony_ci pa_assert(c); 67253a5a1b3Sopenharmony_ci 67353a5a1b3Sopenharmony_ci sinks = get_sinks(c, &n); 67453a5a1b3Sopenharmony_ci 67553a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, sinks, n); 67653a5a1b3Sopenharmony_ci 67753a5a1b3Sopenharmony_ci pa_xfree(sinks); 67853a5a1b3Sopenharmony_ci} 67953a5a1b3Sopenharmony_ci 68053a5a1b3Sopenharmony_cistatic void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { 68153a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 68253a5a1b3Sopenharmony_ci pa_dbusiface_device *fallback_sink; 68353a5a1b3Sopenharmony_ci const char *object_path; 68453a5a1b3Sopenharmony_ci 68553a5a1b3Sopenharmony_ci pa_assert(conn); 68653a5a1b3Sopenharmony_ci pa_assert(msg); 68753a5a1b3Sopenharmony_ci pa_assert(c); 68853a5a1b3Sopenharmony_ci 68953a5a1b3Sopenharmony_ci if (!c->fallback_sink) { 69053a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, 69153a5a1b3Sopenharmony_ci "There are no sinks, and therefore no fallback sink either."); 69253a5a1b3Sopenharmony_ci return; 69353a5a1b3Sopenharmony_ci } 69453a5a1b3Sopenharmony_ci 69553a5a1b3Sopenharmony_ci pa_assert_se((fallback_sink = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)))); 69653a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(fallback_sink); 69753a5a1b3Sopenharmony_ci 69853a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); 69953a5a1b3Sopenharmony_ci} 70053a5a1b3Sopenharmony_ci 70153a5a1b3Sopenharmony_cistatic void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { 70253a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 70353a5a1b3Sopenharmony_ci pa_dbusiface_device *fallback_sink; 70453a5a1b3Sopenharmony_ci const char *object_path; 70553a5a1b3Sopenharmony_ci 70653a5a1b3Sopenharmony_ci pa_assert(conn); 70753a5a1b3Sopenharmony_ci pa_assert(msg); 70853a5a1b3Sopenharmony_ci pa_assert(iter); 70953a5a1b3Sopenharmony_ci pa_assert(c); 71053a5a1b3Sopenharmony_ci 71153a5a1b3Sopenharmony_ci if (!c->fallback_sink) { 71253a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, 71353a5a1b3Sopenharmony_ci "There are no sinks, and therefore no fallback sink either."); 71453a5a1b3Sopenharmony_ci return; 71553a5a1b3Sopenharmony_ci } 71653a5a1b3Sopenharmony_ci 71753a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(iter, &object_path); 71853a5a1b3Sopenharmony_ci 71953a5a1b3Sopenharmony_ci if (!(fallback_sink = pa_hashmap_get(c->sinks_by_path, object_path))) { 72053a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", object_path); 72153a5a1b3Sopenharmony_ci return; 72253a5a1b3Sopenharmony_ci } 72353a5a1b3Sopenharmony_ci 72453a5a1b3Sopenharmony_ci pa_core_set_configured_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink)->name); 72553a5a1b3Sopenharmony_ci 72653a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 72753a5a1b3Sopenharmony_ci} 72853a5a1b3Sopenharmony_ci 72953a5a1b3Sopenharmony_ci/* The caller frees the array, but not the strings. */ 73053a5a1b3Sopenharmony_cistatic const char **get_sources(pa_dbusiface_core *c, unsigned *n) { 73153a5a1b3Sopenharmony_ci const char **sources; 73253a5a1b3Sopenharmony_ci unsigned i = 0; 73353a5a1b3Sopenharmony_ci void *state = NULL; 73453a5a1b3Sopenharmony_ci pa_dbusiface_device *source; 73553a5a1b3Sopenharmony_ci 73653a5a1b3Sopenharmony_ci pa_assert(c); 73753a5a1b3Sopenharmony_ci pa_assert(n); 73853a5a1b3Sopenharmony_ci 73953a5a1b3Sopenharmony_ci *n = pa_hashmap_size(c->sources_by_index); 74053a5a1b3Sopenharmony_ci 74153a5a1b3Sopenharmony_ci if (*n == 0) 74253a5a1b3Sopenharmony_ci return NULL; 74353a5a1b3Sopenharmony_ci 74453a5a1b3Sopenharmony_ci sources = pa_xnew(const char *, *n); 74553a5a1b3Sopenharmony_ci 74653a5a1b3Sopenharmony_ci PA_HASHMAP_FOREACH(source, c->sources_by_index, state) 74753a5a1b3Sopenharmony_ci sources[i++] = pa_dbusiface_device_get_path(source); 74853a5a1b3Sopenharmony_ci 74953a5a1b3Sopenharmony_ci return sources; 75053a5a1b3Sopenharmony_ci} 75153a5a1b3Sopenharmony_ci 75253a5a1b3Sopenharmony_cistatic void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata) { 75353a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 75453a5a1b3Sopenharmony_ci const char **sources; 75553a5a1b3Sopenharmony_ci unsigned n; 75653a5a1b3Sopenharmony_ci 75753a5a1b3Sopenharmony_ci pa_assert(conn); 75853a5a1b3Sopenharmony_ci pa_assert(msg); 75953a5a1b3Sopenharmony_ci pa_assert(c); 76053a5a1b3Sopenharmony_ci 76153a5a1b3Sopenharmony_ci sources = get_sources(c, &n); 76253a5a1b3Sopenharmony_ci 76353a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, sources, n); 76453a5a1b3Sopenharmony_ci 76553a5a1b3Sopenharmony_ci pa_xfree(sources); 76653a5a1b3Sopenharmony_ci} 76753a5a1b3Sopenharmony_ci 76853a5a1b3Sopenharmony_cistatic void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata) { 76953a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 77053a5a1b3Sopenharmony_ci pa_dbusiface_device *fallback_source; 77153a5a1b3Sopenharmony_ci const char *object_path; 77253a5a1b3Sopenharmony_ci 77353a5a1b3Sopenharmony_ci pa_assert(conn); 77453a5a1b3Sopenharmony_ci pa_assert(msg); 77553a5a1b3Sopenharmony_ci pa_assert(c); 77653a5a1b3Sopenharmony_ci 77753a5a1b3Sopenharmony_ci if (!c->fallback_source) { 77853a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, 77953a5a1b3Sopenharmony_ci "There are no sources, and therefore no fallback source either."); 78053a5a1b3Sopenharmony_ci return; 78153a5a1b3Sopenharmony_ci } 78253a5a1b3Sopenharmony_ci 78353a5a1b3Sopenharmony_ci pa_assert_se((fallback_source = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index)))); 78453a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(fallback_source); 78553a5a1b3Sopenharmony_ci 78653a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); 78753a5a1b3Sopenharmony_ci} 78853a5a1b3Sopenharmony_ci 78953a5a1b3Sopenharmony_cistatic void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { 79053a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 79153a5a1b3Sopenharmony_ci pa_dbusiface_device *fallback_source; 79253a5a1b3Sopenharmony_ci const char *object_path; 79353a5a1b3Sopenharmony_ci 79453a5a1b3Sopenharmony_ci pa_assert(conn); 79553a5a1b3Sopenharmony_ci pa_assert(msg); 79653a5a1b3Sopenharmony_ci pa_assert(iter); 79753a5a1b3Sopenharmony_ci pa_assert(c); 79853a5a1b3Sopenharmony_ci 79953a5a1b3Sopenharmony_ci if (!c->fallback_source) { 80053a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, 80153a5a1b3Sopenharmony_ci "There are no sources, and therefore no fallback source either."); 80253a5a1b3Sopenharmony_ci return; 80353a5a1b3Sopenharmony_ci } 80453a5a1b3Sopenharmony_ci 80553a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(iter, &object_path); 80653a5a1b3Sopenharmony_ci 80753a5a1b3Sopenharmony_ci if (!(fallback_source = pa_hashmap_get(c->sources_by_path, object_path))) { 80853a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", object_path); 80953a5a1b3Sopenharmony_ci return; 81053a5a1b3Sopenharmony_ci } 81153a5a1b3Sopenharmony_ci 81253a5a1b3Sopenharmony_ci pa_core_set_configured_default_source(c->core, pa_dbusiface_device_get_source(fallback_source)->name); 81353a5a1b3Sopenharmony_ci 81453a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 81553a5a1b3Sopenharmony_ci} 81653a5a1b3Sopenharmony_ci 81753a5a1b3Sopenharmony_ci/* The caller frees the array, but not the strings. */ 81853a5a1b3Sopenharmony_cistatic const char **get_playback_streams(pa_dbusiface_core *c, unsigned *n) { 81953a5a1b3Sopenharmony_ci const char **streams; 82053a5a1b3Sopenharmony_ci unsigned i = 0; 82153a5a1b3Sopenharmony_ci void *state = NULL; 82253a5a1b3Sopenharmony_ci pa_dbusiface_stream *stream; 82353a5a1b3Sopenharmony_ci 82453a5a1b3Sopenharmony_ci pa_assert(c); 82553a5a1b3Sopenharmony_ci pa_assert(n); 82653a5a1b3Sopenharmony_ci 82753a5a1b3Sopenharmony_ci *n = pa_hashmap_size(c->playback_streams); 82853a5a1b3Sopenharmony_ci 82953a5a1b3Sopenharmony_ci if (*n == 0) 83053a5a1b3Sopenharmony_ci return NULL; 83153a5a1b3Sopenharmony_ci 83253a5a1b3Sopenharmony_ci streams = pa_xnew(const char *, *n); 83353a5a1b3Sopenharmony_ci 83453a5a1b3Sopenharmony_ci PA_HASHMAP_FOREACH(stream, c->playback_streams, state) 83553a5a1b3Sopenharmony_ci streams[i++] = pa_dbusiface_stream_get_path(stream); 83653a5a1b3Sopenharmony_ci 83753a5a1b3Sopenharmony_ci return streams; 83853a5a1b3Sopenharmony_ci} 83953a5a1b3Sopenharmony_ci 84053a5a1b3Sopenharmony_cistatic void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata) { 84153a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 84253a5a1b3Sopenharmony_ci const char **playback_streams; 84353a5a1b3Sopenharmony_ci unsigned n; 84453a5a1b3Sopenharmony_ci 84553a5a1b3Sopenharmony_ci pa_assert(conn); 84653a5a1b3Sopenharmony_ci pa_assert(msg); 84753a5a1b3Sopenharmony_ci pa_assert(c); 84853a5a1b3Sopenharmony_ci 84953a5a1b3Sopenharmony_ci playback_streams = get_playback_streams(c, &n); 85053a5a1b3Sopenharmony_ci 85153a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, playback_streams, n); 85253a5a1b3Sopenharmony_ci 85353a5a1b3Sopenharmony_ci pa_xfree(playback_streams); 85453a5a1b3Sopenharmony_ci} 85553a5a1b3Sopenharmony_ci 85653a5a1b3Sopenharmony_ci/* The caller frees the array, but not the strings. */ 85753a5a1b3Sopenharmony_cistatic const char **get_record_streams(pa_dbusiface_core *c, unsigned *n) { 85853a5a1b3Sopenharmony_ci const char **streams; 85953a5a1b3Sopenharmony_ci unsigned i = 0; 86053a5a1b3Sopenharmony_ci void *state = NULL; 86153a5a1b3Sopenharmony_ci pa_dbusiface_stream *stream; 86253a5a1b3Sopenharmony_ci 86353a5a1b3Sopenharmony_ci pa_assert(c); 86453a5a1b3Sopenharmony_ci pa_assert(n); 86553a5a1b3Sopenharmony_ci 86653a5a1b3Sopenharmony_ci *n = pa_hashmap_size(c->record_streams); 86753a5a1b3Sopenharmony_ci 86853a5a1b3Sopenharmony_ci if (*n == 0) 86953a5a1b3Sopenharmony_ci return NULL; 87053a5a1b3Sopenharmony_ci 87153a5a1b3Sopenharmony_ci streams = pa_xnew(const char *, *n); 87253a5a1b3Sopenharmony_ci 87353a5a1b3Sopenharmony_ci PA_HASHMAP_FOREACH(stream, c->record_streams, state) 87453a5a1b3Sopenharmony_ci streams[i++] = pa_dbusiface_stream_get_path(stream); 87553a5a1b3Sopenharmony_ci 87653a5a1b3Sopenharmony_ci return streams; 87753a5a1b3Sopenharmony_ci} 87853a5a1b3Sopenharmony_ci 87953a5a1b3Sopenharmony_cistatic void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata) { 88053a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 88153a5a1b3Sopenharmony_ci const char **record_streams; 88253a5a1b3Sopenharmony_ci unsigned n; 88353a5a1b3Sopenharmony_ci 88453a5a1b3Sopenharmony_ci pa_assert(conn); 88553a5a1b3Sopenharmony_ci pa_assert(msg); 88653a5a1b3Sopenharmony_ci pa_assert(c); 88753a5a1b3Sopenharmony_ci 88853a5a1b3Sopenharmony_ci record_streams = get_record_streams(c, &n); 88953a5a1b3Sopenharmony_ci 89053a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, record_streams, n); 89153a5a1b3Sopenharmony_ci 89253a5a1b3Sopenharmony_ci pa_xfree(record_streams); 89353a5a1b3Sopenharmony_ci} 89453a5a1b3Sopenharmony_ci 89553a5a1b3Sopenharmony_ci/* The caller frees the array, but not the strings. */ 89653a5a1b3Sopenharmony_cistatic const char **get_samples(pa_dbusiface_core *c, unsigned *n) { 89753a5a1b3Sopenharmony_ci const char **samples; 89853a5a1b3Sopenharmony_ci unsigned i = 0; 89953a5a1b3Sopenharmony_ci void *state = NULL; 90053a5a1b3Sopenharmony_ci pa_dbusiface_sample *sample; 90153a5a1b3Sopenharmony_ci 90253a5a1b3Sopenharmony_ci pa_assert(c); 90353a5a1b3Sopenharmony_ci pa_assert(n); 90453a5a1b3Sopenharmony_ci 90553a5a1b3Sopenharmony_ci *n = pa_hashmap_size(c->samples); 90653a5a1b3Sopenharmony_ci 90753a5a1b3Sopenharmony_ci if (*n == 0) 90853a5a1b3Sopenharmony_ci return NULL; 90953a5a1b3Sopenharmony_ci 91053a5a1b3Sopenharmony_ci samples = pa_xnew(const char *, *n); 91153a5a1b3Sopenharmony_ci 91253a5a1b3Sopenharmony_ci PA_HASHMAP_FOREACH(sample, c->samples, state) 91353a5a1b3Sopenharmony_ci samples[i++] = pa_dbusiface_sample_get_path(sample); 91453a5a1b3Sopenharmony_ci 91553a5a1b3Sopenharmony_ci return samples; 91653a5a1b3Sopenharmony_ci} 91753a5a1b3Sopenharmony_ci 91853a5a1b3Sopenharmony_cistatic void handle_get_samples(DBusConnection *conn, DBusMessage *msg, void *userdata) { 91953a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 92053a5a1b3Sopenharmony_ci const char **samples; 92153a5a1b3Sopenharmony_ci unsigned n; 92253a5a1b3Sopenharmony_ci 92353a5a1b3Sopenharmony_ci pa_assert(conn); 92453a5a1b3Sopenharmony_ci pa_assert(msg); 92553a5a1b3Sopenharmony_ci pa_assert(c); 92653a5a1b3Sopenharmony_ci 92753a5a1b3Sopenharmony_ci samples = get_samples(c, &n); 92853a5a1b3Sopenharmony_ci 92953a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, samples, n); 93053a5a1b3Sopenharmony_ci 93153a5a1b3Sopenharmony_ci pa_xfree(samples); 93253a5a1b3Sopenharmony_ci} 93353a5a1b3Sopenharmony_ci 93453a5a1b3Sopenharmony_ci/* The caller frees the array, but not the strings. */ 93553a5a1b3Sopenharmony_cistatic const char **get_modules(pa_dbusiface_core *c, unsigned *n) { 93653a5a1b3Sopenharmony_ci const char **modules; 93753a5a1b3Sopenharmony_ci unsigned i = 0; 93853a5a1b3Sopenharmony_ci void *state = NULL; 93953a5a1b3Sopenharmony_ci pa_dbusiface_module *module; 94053a5a1b3Sopenharmony_ci 94153a5a1b3Sopenharmony_ci pa_assert(c); 94253a5a1b3Sopenharmony_ci pa_assert(n); 94353a5a1b3Sopenharmony_ci 94453a5a1b3Sopenharmony_ci *n = pa_hashmap_size(c->modules); 94553a5a1b3Sopenharmony_ci 94653a5a1b3Sopenharmony_ci if (*n == 0) 94753a5a1b3Sopenharmony_ci return NULL; 94853a5a1b3Sopenharmony_ci 94953a5a1b3Sopenharmony_ci modules = pa_xnew(const char *, *n); 95053a5a1b3Sopenharmony_ci 95153a5a1b3Sopenharmony_ci PA_HASHMAP_FOREACH(module, c->modules, state) 95253a5a1b3Sopenharmony_ci modules[i++] = pa_dbusiface_module_get_path(module); 95353a5a1b3Sopenharmony_ci 95453a5a1b3Sopenharmony_ci return modules; 95553a5a1b3Sopenharmony_ci} 95653a5a1b3Sopenharmony_ci 95753a5a1b3Sopenharmony_cistatic void handle_get_modules(DBusConnection *conn, DBusMessage *msg, void *userdata) { 95853a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 95953a5a1b3Sopenharmony_ci const char **modules; 96053a5a1b3Sopenharmony_ci unsigned n; 96153a5a1b3Sopenharmony_ci 96253a5a1b3Sopenharmony_ci pa_assert(conn); 96353a5a1b3Sopenharmony_ci pa_assert(msg); 96453a5a1b3Sopenharmony_ci pa_assert(c); 96553a5a1b3Sopenharmony_ci 96653a5a1b3Sopenharmony_ci modules = get_modules(c, &n); 96753a5a1b3Sopenharmony_ci 96853a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, modules, n); 96953a5a1b3Sopenharmony_ci 97053a5a1b3Sopenharmony_ci pa_xfree(modules); 97153a5a1b3Sopenharmony_ci} 97253a5a1b3Sopenharmony_ci 97353a5a1b3Sopenharmony_ci/* The caller frees the array, but not the strings. */ 97453a5a1b3Sopenharmony_cistatic const char **get_clients(pa_dbusiface_core *c, unsigned *n) { 97553a5a1b3Sopenharmony_ci const char **clients; 97653a5a1b3Sopenharmony_ci unsigned i = 0; 97753a5a1b3Sopenharmony_ci void *state = NULL; 97853a5a1b3Sopenharmony_ci pa_dbusiface_client *client; 97953a5a1b3Sopenharmony_ci 98053a5a1b3Sopenharmony_ci pa_assert(c); 98153a5a1b3Sopenharmony_ci pa_assert(n); 98253a5a1b3Sopenharmony_ci 98353a5a1b3Sopenharmony_ci *n = pa_hashmap_size(c->clients); 98453a5a1b3Sopenharmony_ci 98553a5a1b3Sopenharmony_ci if (*n == 0) 98653a5a1b3Sopenharmony_ci return NULL; 98753a5a1b3Sopenharmony_ci 98853a5a1b3Sopenharmony_ci clients = pa_xnew(const char *, *n); 98953a5a1b3Sopenharmony_ci 99053a5a1b3Sopenharmony_ci PA_HASHMAP_FOREACH(client, c->clients, state) 99153a5a1b3Sopenharmony_ci clients[i++] = pa_dbusiface_client_get_path(client); 99253a5a1b3Sopenharmony_ci 99353a5a1b3Sopenharmony_ci return clients; 99453a5a1b3Sopenharmony_ci} 99553a5a1b3Sopenharmony_ci 99653a5a1b3Sopenharmony_cistatic void handle_get_clients(DBusConnection *conn, DBusMessage *msg, void *userdata) { 99753a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 99853a5a1b3Sopenharmony_ci const char **clients; 99953a5a1b3Sopenharmony_ci unsigned n; 100053a5a1b3Sopenharmony_ci 100153a5a1b3Sopenharmony_ci pa_assert(conn); 100253a5a1b3Sopenharmony_ci pa_assert(msg); 100353a5a1b3Sopenharmony_ci pa_assert(c); 100453a5a1b3Sopenharmony_ci 100553a5a1b3Sopenharmony_ci clients = get_clients(c, &n); 100653a5a1b3Sopenharmony_ci 100753a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, clients, n); 100853a5a1b3Sopenharmony_ci 100953a5a1b3Sopenharmony_ci pa_xfree(clients); 101053a5a1b3Sopenharmony_ci} 101153a5a1b3Sopenharmony_ci 101253a5a1b3Sopenharmony_cistatic const char *get_my_client(pa_dbusiface_core *c, DBusConnection *conn) { 101353a5a1b3Sopenharmony_ci pa_client *my_client; 101453a5a1b3Sopenharmony_ci 101553a5a1b3Sopenharmony_ci pa_assert(c); 101653a5a1b3Sopenharmony_ci pa_assert(conn); 101753a5a1b3Sopenharmony_ci 101853a5a1b3Sopenharmony_ci pa_assert_se((my_client = pa_dbus_protocol_get_client(c->dbus_protocol, conn))); 101953a5a1b3Sopenharmony_ci 102053a5a1b3Sopenharmony_ci return pa_dbusiface_client_get_path(pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(my_client->index))); 102153a5a1b3Sopenharmony_ci} 102253a5a1b3Sopenharmony_ci 102353a5a1b3Sopenharmony_cistatic void handle_get_my_client(DBusConnection *conn, DBusMessage *msg, void *userdata) { 102453a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 102553a5a1b3Sopenharmony_ci const char *my_client; 102653a5a1b3Sopenharmony_ci 102753a5a1b3Sopenharmony_ci pa_assert(conn); 102853a5a1b3Sopenharmony_ci pa_assert(msg); 102953a5a1b3Sopenharmony_ci pa_assert(c); 103053a5a1b3Sopenharmony_ci 103153a5a1b3Sopenharmony_ci my_client = get_my_client(c, conn); 103253a5a1b3Sopenharmony_ci 103353a5a1b3Sopenharmony_ci pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &my_client); 103453a5a1b3Sopenharmony_ci} 103553a5a1b3Sopenharmony_ci 103653a5a1b3Sopenharmony_cistatic void handle_get_extensions(DBusConnection *conn, DBusMessage *msg, void *userdata) { 103753a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 103853a5a1b3Sopenharmony_ci const char **extensions; 103953a5a1b3Sopenharmony_ci unsigned n; 104053a5a1b3Sopenharmony_ci 104153a5a1b3Sopenharmony_ci pa_assert(conn); 104253a5a1b3Sopenharmony_ci pa_assert(msg); 104353a5a1b3Sopenharmony_ci pa_assert(c); 104453a5a1b3Sopenharmony_ci 104553a5a1b3Sopenharmony_ci extensions = pa_dbus_protocol_get_extensions(c->dbus_protocol, &n); 104653a5a1b3Sopenharmony_ci 104753a5a1b3Sopenharmony_ci pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_STRING, extensions, n); 104853a5a1b3Sopenharmony_ci 104953a5a1b3Sopenharmony_ci pa_xfree(extensions); 105053a5a1b3Sopenharmony_ci} 105153a5a1b3Sopenharmony_ci 105253a5a1b3Sopenharmony_cistatic void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) { 105353a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 105453a5a1b3Sopenharmony_ci DBusMessage *reply = NULL; 105553a5a1b3Sopenharmony_ci DBusMessageIter msg_iter; 105653a5a1b3Sopenharmony_ci DBusMessageIter dict_iter; 105753a5a1b3Sopenharmony_ci dbus_uint32_t interface_revision; 105853a5a1b3Sopenharmony_ci const char *server_name; 105953a5a1b3Sopenharmony_ci const char *version; 106053a5a1b3Sopenharmony_ci dbus_bool_t is_local; 106153a5a1b3Sopenharmony_ci char *username; 106253a5a1b3Sopenharmony_ci char *hostname; 106353a5a1b3Sopenharmony_ci dbus_uint32_t *default_channels; 106453a5a1b3Sopenharmony_ci unsigned n_default_channels; 106553a5a1b3Sopenharmony_ci dbus_uint32_t default_sample_format; 106653a5a1b3Sopenharmony_ci dbus_uint32_t default_sample_rate; 106753a5a1b3Sopenharmony_ci dbus_uint32_t alternate_sample_rate; 106853a5a1b3Sopenharmony_ci const char **cards; 106953a5a1b3Sopenharmony_ci unsigned n_cards; 107053a5a1b3Sopenharmony_ci const char **sinks; 107153a5a1b3Sopenharmony_ci unsigned n_sinks; 107253a5a1b3Sopenharmony_ci const char *fallback_sink; 107353a5a1b3Sopenharmony_ci const char **sources; 107453a5a1b3Sopenharmony_ci unsigned n_sources; 107553a5a1b3Sopenharmony_ci const char *fallback_source; 107653a5a1b3Sopenharmony_ci const char **playback_streams; 107753a5a1b3Sopenharmony_ci unsigned n_playback_streams; 107853a5a1b3Sopenharmony_ci const char **record_streams; 107953a5a1b3Sopenharmony_ci unsigned n_record_streams; 108053a5a1b3Sopenharmony_ci const char **samples; 108153a5a1b3Sopenharmony_ci unsigned n_samples; 108253a5a1b3Sopenharmony_ci const char **modules; 108353a5a1b3Sopenharmony_ci unsigned n_modules; 108453a5a1b3Sopenharmony_ci const char **clients; 108553a5a1b3Sopenharmony_ci unsigned n_clients; 108653a5a1b3Sopenharmony_ci const char *my_client; 108753a5a1b3Sopenharmony_ci const char **extensions; 108853a5a1b3Sopenharmony_ci unsigned n_extensions; 108953a5a1b3Sopenharmony_ci 109053a5a1b3Sopenharmony_ci pa_assert(conn); 109153a5a1b3Sopenharmony_ci pa_assert(msg); 109253a5a1b3Sopenharmony_ci pa_assert(c); 109353a5a1b3Sopenharmony_ci 109453a5a1b3Sopenharmony_ci interface_revision = INTERFACE_REVISION; 109553a5a1b3Sopenharmony_ci server_name = PACKAGE_NAME; 109653a5a1b3Sopenharmony_ci version = PACKAGE_VERSION; 109753a5a1b3Sopenharmony_ci is_local = get_is_local(conn); 109853a5a1b3Sopenharmony_ci username = pa_get_user_name_malloc(); 109953a5a1b3Sopenharmony_ci hostname = pa_get_host_name_malloc(); 110053a5a1b3Sopenharmony_ci default_channels = get_default_channels(c, &n_default_channels); 110153a5a1b3Sopenharmony_ci default_sample_format = c->core->default_sample_spec.format; 110253a5a1b3Sopenharmony_ci default_sample_rate = c->core->default_sample_spec.rate; 110353a5a1b3Sopenharmony_ci alternate_sample_rate = c->core->alternate_sample_rate; 110453a5a1b3Sopenharmony_ci cards = get_cards(c, &n_cards); 110553a5a1b3Sopenharmony_ci sinks = get_sinks(c, &n_sinks); 110653a5a1b3Sopenharmony_ci fallback_sink = c->fallback_sink 110753a5a1b3Sopenharmony_ci ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index))) 110853a5a1b3Sopenharmony_ci : NULL; 110953a5a1b3Sopenharmony_ci sources = get_sources(c, &n_sources); 111053a5a1b3Sopenharmony_ci fallback_source = c->fallback_source 111153a5a1b3Sopenharmony_ci ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, 111253a5a1b3Sopenharmony_ci PA_UINT32_TO_PTR(c->fallback_source->index))) 111353a5a1b3Sopenharmony_ci : NULL; 111453a5a1b3Sopenharmony_ci playback_streams = get_playback_streams(c, &n_playback_streams); 111553a5a1b3Sopenharmony_ci record_streams = get_record_streams(c, &n_record_streams); 111653a5a1b3Sopenharmony_ci samples = get_samples(c, &n_samples); 111753a5a1b3Sopenharmony_ci modules = get_modules(c, &n_modules); 111853a5a1b3Sopenharmony_ci clients = get_clients(c, &n_clients); 111953a5a1b3Sopenharmony_ci my_client = get_my_client(c, conn); 112053a5a1b3Sopenharmony_ci extensions = pa_dbus_protocol_get_extensions(c->dbus_protocol, &n_extensions); 112153a5a1b3Sopenharmony_ci 112253a5a1b3Sopenharmony_ci pa_assert_se((reply = dbus_message_new_method_return(msg))); 112353a5a1b3Sopenharmony_ci 112453a5a1b3Sopenharmony_ci dbus_message_iter_init_append(reply, &msg_iter); 112553a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter)); 112653a5a1b3Sopenharmony_ci 112753a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INTERFACE_REVISION].property_name, DBUS_TYPE_UINT32, &interface_revision); 112853a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &server_name); 112953a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_VERSION].property_name, DBUS_TYPE_STRING, &version); 113053a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_IS_LOCAL].property_name, DBUS_TYPE_BOOLEAN, &is_local); 113153a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_USERNAME].property_name, DBUS_TYPE_STRING, &username); 113253a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HOSTNAME].property_name, DBUS_TYPE_STRING, &hostname); 113353a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_CHANNELS].property_name, DBUS_TYPE_UINT32, default_channels, n_default_channels); 113453a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT].property_name, DBUS_TYPE_UINT32, &default_sample_format); 113553a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &default_sample_rate); 113653a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &alternate_sample_rate); 113753a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CARDS].property_name, DBUS_TYPE_OBJECT_PATH, cards, n_cards); 113853a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, sinks, n_sinks); 113953a5a1b3Sopenharmony_ci 114053a5a1b3Sopenharmony_ci if (fallback_sink) 114153a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_FALLBACK_SINK].property_name, DBUS_TYPE_OBJECT_PATH, &fallback_sink); 114253a5a1b3Sopenharmony_ci 114353a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SOURCES].property_name, DBUS_TYPE_OBJECT_PATH, sources, n_sources); 114453a5a1b3Sopenharmony_ci 114553a5a1b3Sopenharmony_ci if (fallback_source) 114653a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_FALLBACK_SOURCE].property_name, DBUS_TYPE_OBJECT_PATH, &fallback_source); 114753a5a1b3Sopenharmony_ci 114853a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PLAYBACK_STREAMS].property_name, DBUS_TYPE_OBJECT_PATH, playback_streams, n_playback_streams); 114953a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_RECORD_STREAMS].property_name, DBUS_TYPE_OBJECT_PATH, record_streams, n_record_streams); 115053a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLES].property_name, DBUS_TYPE_OBJECT_PATH, samples, n_samples); 115153a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MODULES].property_name, DBUS_TYPE_OBJECT_PATH, modules, n_modules); 115253a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CLIENTS].property_name, DBUS_TYPE_OBJECT_PATH, clients, n_clients); 115353a5a1b3Sopenharmony_ci pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MY_CLIENT].property_name, DBUS_TYPE_OBJECT_PATH, &my_client); 115453a5a1b3Sopenharmony_ci pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_EXTENSIONS].property_name, DBUS_TYPE_STRING, extensions, n_extensions); 115553a5a1b3Sopenharmony_ci 115653a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter)); 115753a5a1b3Sopenharmony_ci 115853a5a1b3Sopenharmony_ci pa_assert_se(dbus_connection_send(conn, reply, NULL)); 115953a5a1b3Sopenharmony_ci 116053a5a1b3Sopenharmony_ci dbus_message_unref(reply); 116153a5a1b3Sopenharmony_ci 116253a5a1b3Sopenharmony_ci pa_xfree(username); 116353a5a1b3Sopenharmony_ci pa_xfree(hostname); 116453a5a1b3Sopenharmony_ci pa_xfree(default_channels); 116553a5a1b3Sopenharmony_ci pa_xfree(cards); 116653a5a1b3Sopenharmony_ci pa_xfree(sinks); 116753a5a1b3Sopenharmony_ci pa_xfree(sources); 116853a5a1b3Sopenharmony_ci pa_xfree(playback_streams); 116953a5a1b3Sopenharmony_ci pa_xfree(record_streams); 117053a5a1b3Sopenharmony_ci pa_xfree(samples); 117153a5a1b3Sopenharmony_ci pa_xfree(modules); 117253a5a1b3Sopenharmony_ci pa_xfree(clients); 117353a5a1b3Sopenharmony_ci pa_xfree(extensions); 117453a5a1b3Sopenharmony_ci} 117553a5a1b3Sopenharmony_ci 117653a5a1b3Sopenharmony_cistatic void handle_get_card_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { 117753a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 117853a5a1b3Sopenharmony_ci char *card_name; 117953a5a1b3Sopenharmony_ci pa_card *card; 118053a5a1b3Sopenharmony_ci pa_dbusiface_card *dbus_card; 118153a5a1b3Sopenharmony_ci const char *object_path; 118253a5a1b3Sopenharmony_ci 118353a5a1b3Sopenharmony_ci pa_assert(conn); 118453a5a1b3Sopenharmony_ci pa_assert(msg); 118553a5a1b3Sopenharmony_ci pa_assert(c); 118653a5a1b3Sopenharmony_ci 118753a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &card_name, DBUS_TYPE_INVALID)); 118853a5a1b3Sopenharmony_ci 118953a5a1b3Sopenharmony_ci if (!(card = pa_namereg_get(c->core, card_name, PA_NAMEREG_CARD))) { 119053a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such card."); 119153a5a1b3Sopenharmony_ci return; 119253a5a1b3Sopenharmony_ci } 119353a5a1b3Sopenharmony_ci 119453a5a1b3Sopenharmony_ci pa_assert_se((dbus_card = pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(card->index)))); 119553a5a1b3Sopenharmony_ci 119653a5a1b3Sopenharmony_ci object_path = pa_dbusiface_card_get_path(dbus_card); 119753a5a1b3Sopenharmony_ci 119853a5a1b3Sopenharmony_ci pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); 119953a5a1b3Sopenharmony_ci} 120053a5a1b3Sopenharmony_ci 120153a5a1b3Sopenharmony_cistatic void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { 120253a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 120353a5a1b3Sopenharmony_ci char *sink_name; 120453a5a1b3Sopenharmony_ci pa_sink *sink; 120553a5a1b3Sopenharmony_ci pa_dbusiface_device *dbus_sink; 120653a5a1b3Sopenharmony_ci const char *object_path; 120753a5a1b3Sopenharmony_ci 120853a5a1b3Sopenharmony_ci pa_assert(conn); 120953a5a1b3Sopenharmony_ci pa_assert(msg); 121053a5a1b3Sopenharmony_ci pa_assert(c); 121153a5a1b3Sopenharmony_ci 121253a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &sink_name, DBUS_TYPE_INVALID)); 121353a5a1b3Sopenharmony_ci 121453a5a1b3Sopenharmony_ci if (!(sink = pa_namereg_get(c->core, sink_name, PA_NAMEREG_SINK))) { 121553a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", sink_name); 121653a5a1b3Sopenharmony_ci return; 121753a5a1b3Sopenharmony_ci } 121853a5a1b3Sopenharmony_ci 121953a5a1b3Sopenharmony_ci pa_assert_se((dbus_sink = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(sink->index)))); 122053a5a1b3Sopenharmony_ci 122153a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(dbus_sink); 122253a5a1b3Sopenharmony_ci 122353a5a1b3Sopenharmony_ci pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); 122453a5a1b3Sopenharmony_ci} 122553a5a1b3Sopenharmony_ci 122653a5a1b3Sopenharmony_cistatic void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { 122753a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 122853a5a1b3Sopenharmony_ci char *source_name; 122953a5a1b3Sopenharmony_ci pa_source *source; 123053a5a1b3Sopenharmony_ci pa_dbusiface_device *dbus_source; 123153a5a1b3Sopenharmony_ci const char *object_path; 123253a5a1b3Sopenharmony_ci 123353a5a1b3Sopenharmony_ci pa_assert(conn); 123453a5a1b3Sopenharmony_ci pa_assert(msg); 123553a5a1b3Sopenharmony_ci pa_assert(c); 123653a5a1b3Sopenharmony_ci 123753a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &source_name, DBUS_TYPE_INVALID)); 123853a5a1b3Sopenharmony_ci 123953a5a1b3Sopenharmony_ci if (!(source = pa_namereg_get(c->core, source_name, PA_NAMEREG_SOURCE))) { 124053a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", source_name); 124153a5a1b3Sopenharmony_ci return; 124253a5a1b3Sopenharmony_ci } 124353a5a1b3Sopenharmony_ci 124453a5a1b3Sopenharmony_ci pa_assert_se((dbus_source = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(source->index)))); 124553a5a1b3Sopenharmony_ci 124653a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(dbus_source); 124753a5a1b3Sopenharmony_ci 124853a5a1b3Sopenharmony_ci pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); 124953a5a1b3Sopenharmony_ci} 125053a5a1b3Sopenharmony_ci 125153a5a1b3Sopenharmony_cistatic void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { 125253a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 125353a5a1b3Sopenharmony_ci char *sample_name; 125453a5a1b3Sopenharmony_ci pa_scache_entry *sample; 125553a5a1b3Sopenharmony_ci pa_dbusiface_sample *dbus_sample; 125653a5a1b3Sopenharmony_ci const char *object_path; 125753a5a1b3Sopenharmony_ci 125853a5a1b3Sopenharmony_ci pa_assert(conn); 125953a5a1b3Sopenharmony_ci pa_assert(msg); 126053a5a1b3Sopenharmony_ci pa_assert(c); 126153a5a1b3Sopenharmony_ci 126253a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &sample_name, DBUS_TYPE_INVALID)); 126353a5a1b3Sopenharmony_ci 126453a5a1b3Sopenharmony_ci if (!(sample = pa_namereg_get(c->core, sample_name, PA_NAMEREG_SAMPLE))) { 126553a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such sample."); 126653a5a1b3Sopenharmony_ci return; 126753a5a1b3Sopenharmony_ci } 126853a5a1b3Sopenharmony_ci 126953a5a1b3Sopenharmony_ci pa_assert_se((dbus_sample = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(sample->index)))); 127053a5a1b3Sopenharmony_ci 127153a5a1b3Sopenharmony_ci object_path = pa_dbusiface_sample_get_path(dbus_sample); 127253a5a1b3Sopenharmony_ci 127353a5a1b3Sopenharmony_ci pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); 127453a5a1b3Sopenharmony_ci} 127553a5a1b3Sopenharmony_ci 127653a5a1b3Sopenharmony_cistatic void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *userdata) { 127753a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 127853a5a1b3Sopenharmony_ci DBusMessageIter msg_iter; 127953a5a1b3Sopenharmony_ci DBusMessageIter array_iter; 128053a5a1b3Sopenharmony_ci const char *name; 128153a5a1b3Sopenharmony_ci dbus_uint32_t sample_format; 128253a5a1b3Sopenharmony_ci dbus_uint32_t sample_rate; 128353a5a1b3Sopenharmony_ci const dbus_uint32_t *channels; 128453a5a1b3Sopenharmony_ci int n_channels; 128553a5a1b3Sopenharmony_ci const dbus_uint32_t *default_volume; 128653a5a1b3Sopenharmony_ci int n_volume_entries; 128753a5a1b3Sopenharmony_ci pa_proplist *property_list; 128853a5a1b3Sopenharmony_ci const uint8_t *data; 128953a5a1b3Sopenharmony_ci int data_length; 129053a5a1b3Sopenharmony_ci int i; 129153a5a1b3Sopenharmony_ci pa_sample_spec ss; 129253a5a1b3Sopenharmony_ci pa_channel_map map; 129353a5a1b3Sopenharmony_ci pa_memchunk chunk; 129453a5a1b3Sopenharmony_ci uint32_t idx; 129553a5a1b3Sopenharmony_ci pa_dbusiface_sample *dbus_sample = NULL; 129653a5a1b3Sopenharmony_ci pa_scache_entry *sample = NULL; 129753a5a1b3Sopenharmony_ci const char *object_path; 129853a5a1b3Sopenharmony_ci 129953a5a1b3Sopenharmony_ci pa_assert(conn); 130053a5a1b3Sopenharmony_ci pa_assert(msg); 130153a5a1b3Sopenharmony_ci pa_assert(c); 130253a5a1b3Sopenharmony_ci 130353a5a1b3Sopenharmony_ci chunk.memblock = NULL; 130453a5a1b3Sopenharmony_ci 130553a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_init(msg, &msg_iter)); 130653a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(&msg_iter, &name); 130753a5a1b3Sopenharmony_ci 130853a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_next(&msg_iter)); 130953a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(&msg_iter, &sample_format); 131053a5a1b3Sopenharmony_ci 131153a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_next(&msg_iter)); 131253a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(&msg_iter, &sample_rate); 131353a5a1b3Sopenharmony_ci 131453a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_next(&msg_iter)); 131553a5a1b3Sopenharmony_ci dbus_message_iter_recurse(&msg_iter, &array_iter); 131653a5a1b3Sopenharmony_ci dbus_message_iter_get_fixed_array(&array_iter, &channels, &n_channels); 131753a5a1b3Sopenharmony_ci 131853a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_next(&msg_iter)); 131953a5a1b3Sopenharmony_ci dbus_message_iter_recurse(&msg_iter, &array_iter); 132053a5a1b3Sopenharmony_ci dbus_message_iter_get_fixed_array(&array_iter, &default_volume, &n_volume_entries); 132153a5a1b3Sopenharmony_ci 132253a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_next(&msg_iter)); 132353a5a1b3Sopenharmony_ci if (!(property_list = pa_dbus_get_proplist_arg(conn, msg, &msg_iter))) 132453a5a1b3Sopenharmony_ci return; 132553a5a1b3Sopenharmony_ci 132653a5a1b3Sopenharmony_ci dbus_message_iter_recurse(&msg_iter, &array_iter); 132753a5a1b3Sopenharmony_ci dbus_message_iter_get_fixed_array(&array_iter, &data, &data_length); 132853a5a1b3Sopenharmony_ci 132953a5a1b3Sopenharmony_ci if (!pa_sample_format_valid(sample_format)) { 133053a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format."); 133153a5a1b3Sopenharmony_ci goto finish; 133253a5a1b3Sopenharmony_ci } 133353a5a1b3Sopenharmony_ci 133453a5a1b3Sopenharmony_ci if (!pa_sample_rate_valid(sample_rate)) { 133553a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate."); 133653a5a1b3Sopenharmony_ci goto finish; 133753a5a1b3Sopenharmony_ci } 133853a5a1b3Sopenharmony_ci 133953a5a1b3Sopenharmony_ci if (n_channels <= 0) { 134053a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel map."); 134153a5a1b3Sopenharmony_ci goto finish; 134253a5a1b3Sopenharmony_ci } 134353a5a1b3Sopenharmony_ci 134453a5a1b3Sopenharmony_ci if (n_channels > (int) PA_CHANNELS_MAX) { 134553a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, 134653a5a1b3Sopenharmony_ci "Too many channels: %i. The maximum is %u.", n_channels, PA_CHANNELS_MAX); 134753a5a1b3Sopenharmony_ci goto finish; 134853a5a1b3Sopenharmony_ci } 134953a5a1b3Sopenharmony_ci 135053a5a1b3Sopenharmony_ci for (i = 0; i < n_channels; ++i) { 135153a5a1b3Sopenharmony_ci if (channels[i] >= PA_CHANNEL_POSITION_MAX) { 135253a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position."); 135353a5a1b3Sopenharmony_ci goto finish; 135453a5a1b3Sopenharmony_ci } 135553a5a1b3Sopenharmony_ci } 135653a5a1b3Sopenharmony_ci 135753a5a1b3Sopenharmony_ci if (n_volume_entries != 0 && n_volume_entries != n_channels) { 135853a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, 135953a5a1b3Sopenharmony_ci "The channels and default_volume arguments have different number of elements (%i and %i, resp).", 136053a5a1b3Sopenharmony_ci n_channels, n_volume_entries); 136153a5a1b3Sopenharmony_ci goto finish; 136253a5a1b3Sopenharmony_ci } 136353a5a1b3Sopenharmony_ci 136453a5a1b3Sopenharmony_ci for (i = 0; i < n_volume_entries; ++i) { 136553a5a1b3Sopenharmony_ci if (!PA_VOLUME_IS_VALID(default_volume[i])) { 136653a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u.", default_volume[i]); 136753a5a1b3Sopenharmony_ci goto finish; 136853a5a1b3Sopenharmony_ci } 136953a5a1b3Sopenharmony_ci } 137053a5a1b3Sopenharmony_ci 137153a5a1b3Sopenharmony_ci if (data_length == 0) { 137253a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty data."); 137353a5a1b3Sopenharmony_ci goto finish; 137453a5a1b3Sopenharmony_ci } 137553a5a1b3Sopenharmony_ci 137653a5a1b3Sopenharmony_ci if (data_length > PA_SCACHE_ENTRY_SIZE_MAX) { 137753a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, 137853a5a1b3Sopenharmony_ci "Too big sample: %i bytes. The maximum sample length is %u bytes.", 137953a5a1b3Sopenharmony_ci data_length, PA_SCACHE_ENTRY_SIZE_MAX); 138053a5a1b3Sopenharmony_ci goto finish; 138153a5a1b3Sopenharmony_ci } 138253a5a1b3Sopenharmony_ci 138353a5a1b3Sopenharmony_ci ss.format = sample_format; 138453a5a1b3Sopenharmony_ci ss.rate = sample_rate; 138553a5a1b3Sopenharmony_ci ss.channels = n_channels; 138653a5a1b3Sopenharmony_ci 138753a5a1b3Sopenharmony_ci pa_assert(pa_sample_spec_valid(&ss)); 138853a5a1b3Sopenharmony_ci 138953a5a1b3Sopenharmony_ci if (!pa_frame_aligned(data_length, &ss)) { 139053a5a1b3Sopenharmony_ci char buf[PA_SAMPLE_SPEC_SNPRINT_MAX]; 139153a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, 139253a5a1b3Sopenharmony_ci "The sample length (%i bytes) doesn't align with the sample format and channels (%s).", 139353a5a1b3Sopenharmony_ci data_length, pa_sample_spec_snprint(buf, sizeof(buf), &ss)); 139453a5a1b3Sopenharmony_ci goto finish; 139553a5a1b3Sopenharmony_ci } 139653a5a1b3Sopenharmony_ci 139753a5a1b3Sopenharmony_ci map.channels = n_channels; 139853a5a1b3Sopenharmony_ci for (i = 0; i < n_channels; ++i) 139953a5a1b3Sopenharmony_ci map.map[i] = channels[i]; 140053a5a1b3Sopenharmony_ci 140153a5a1b3Sopenharmony_ci chunk.memblock = pa_memblock_new(c->core->mempool, data_length); 140253a5a1b3Sopenharmony_ci chunk.index = 0; 140353a5a1b3Sopenharmony_ci chunk.length = data_length; 140453a5a1b3Sopenharmony_ci 140553a5a1b3Sopenharmony_ci memcpy(pa_memblock_acquire(chunk.memblock), data, data_length); 140653a5a1b3Sopenharmony_ci pa_memblock_release(chunk.memblock); 140753a5a1b3Sopenharmony_ci 140853a5a1b3Sopenharmony_ci if (pa_scache_add_item(c->core, name, &ss, &map, &chunk, property_list, &idx) < 0) { 140953a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Adding the sample failed."); 141053a5a1b3Sopenharmony_ci goto finish; 141153a5a1b3Sopenharmony_ci } 141253a5a1b3Sopenharmony_ci 141353a5a1b3Sopenharmony_ci pa_assert_se(sample = pa_idxset_get_by_index(c->core->scache, idx)); 141453a5a1b3Sopenharmony_ci 141553a5a1b3Sopenharmony_ci if (n_volume_entries > 0) { 141653a5a1b3Sopenharmony_ci sample->volume.channels = n_channels; 141753a5a1b3Sopenharmony_ci for (i = 0; i < n_volume_entries; ++i) 141853a5a1b3Sopenharmony_ci sample->volume.values[i] = default_volume[i]; 141953a5a1b3Sopenharmony_ci sample->volume_is_set = true; 142053a5a1b3Sopenharmony_ci } else { 142153a5a1b3Sopenharmony_ci sample->volume_is_set = false; 142253a5a1b3Sopenharmony_ci } 142353a5a1b3Sopenharmony_ci 142453a5a1b3Sopenharmony_ci dbus_sample = pa_dbusiface_sample_new(c, sample); 142553a5a1b3Sopenharmony_ci pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), dbus_sample); 142653a5a1b3Sopenharmony_ci 142753a5a1b3Sopenharmony_ci object_path = pa_dbusiface_sample_get_path(dbus_sample); 142853a5a1b3Sopenharmony_ci 142953a5a1b3Sopenharmony_ci pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); 143053a5a1b3Sopenharmony_ci 143153a5a1b3Sopenharmony_cifinish: 143253a5a1b3Sopenharmony_ci if (property_list) 143353a5a1b3Sopenharmony_ci pa_proplist_free(property_list); 143453a5a1b3Sopenharmony_ci 143553a5a1b3Sopenharmony_ci if (chunk.memblock) 143653a5a1b3Sopenharmony_ci pa_memblock_unref(chunk.memblock); 143753a5a1b3Sopenharmony_ci} 143853a5a1b3Sopenharmony_ci 143953a5a1b3Sopenharmony_cistatic bool contains_space(const char *string) { 144053a5a1b3Sopenharmony_ci const char *p; 144153a5a1b3Sopenharmony_ci 144253a5a1b3Sopenharmony_ci pa_assert(string); 144353a5a1b3Sopenharmony_ci 144453a5a1b3Sopenharmony_ci for (p = string; *p; ++p) { 144553a5a1b3Sopenharmony_ci if (isspace((unsigned char)*p)) 144653a5a1b3Sopenharmony_ci return true; 144753a5a1b3Sopenharmony_ci } 144853a5a1b3Sopenharmony_ci 144953a5a1b3Sopenharmony_ci return false; 145053a5a1b3Sopenharmony_ci} 145153a5a1b3Sopenharmony_ci 145253a5a1b3Sopenharmony_cistatic void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *userdata) { 145353a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 145453a5a1b3Sopenharmony_ci DBusMessageIter msg_iter; 145553a5a1b3Sopenharmony_ci DBusMessageIter dict_iter; 145653a5a1b3Sopenharmony_ci DBusMessageIter dict_entry_iter; 145753a5a1b3Sopenharmony_ci char *name = NULL; 145853a5a1b3Sopenharmony_ci const char *key = NULL; 145953a5a1b3Sopenharmony_ci const char *value = NULL; 146053a5a1b3Sopenharmony_ci char *escaped_value = NULL; 146153a5a1b3Sopenharmony_ci pa_strbuf *arg_buffer = NULL; 146253a5a1b3Sopenharmony_ci char *arg_string = NULL; 146353a5a1b3Sopenharmony_ci pa_module *module = NULL; 146453a5a1b3Sopenharmony_ci pa_dbusiface_module *dbus_module = NULL; 146553a5a1b3Sopenharmony_ci const char *object_path = NULL; 146653a5a1b3Sopenharmony_ci 146753a5a1b3Sopenharmony_ci pa_assert(conn); 146853a5a1b3Sopenharmony_ci pa_assert(msg); 146953a5a1b3Sopenharmony_ci pa_assert(c); 147053a5a1b3Sopenharmony_ci 147153a5a1b3Sopenharmony_ci if (c->core->disallow_module_loading) { 147253a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "The server is configured to disallow module loading."); 147353a5a1b3Sopenharmony_ci return; 147453a5a1b3Sopenharmony_ci } 147553a5a1b3Sopenharmony_ci 147653a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_init(msg, &msg_iter)); 147753a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(&msg_iter, &name); 147853a5a1b3Sopenharmony_ci 147953a5a1b3Sopenharmony_ci arg_buffer = pa_strbuf_new(); 148053a5a1b3Sopenharmony_ci 148153a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_next(&msg_iter)); 148253a5a1b3Sopenharmony_ci dbus_message_iter_recurse(&msg_iter, &dict_iter); 148353a5a1b3Sopenharmony_ci 148453a5a1b3Sopenharmony_ci while (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_INVALID) { 148553a5a1b3Sopenharmony_ci if (!pa_strbuf_isempty(arg_buffer)) 148653a5a1b3Sopenharmony_ci pa_strbuf_putc(arg_buffer, ' '); 148753a5a1b3Sopenharmony_ci 148853a5a1b3Sopenharmony_ci dbus_message_iter_recurse(&dict_iter, &dict_entry_iter); 148953a5a1b3Sopenharmony_ci 149053a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(&dict_entry_iter, &key); 149153a5a1b3Sopenharmony_ci 149253a5a1b3Sopenharmony_ci if (strlen(key) <= 0 || !pa_ascii_valid(key) || contains_space(key)) { 149353a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid module argument name: %s", key); 149453a5a1b3Sopenharmony_ci goto finish; 149553a5a1b3Sopenharmony_ci } 149653a5a1b3Sopenharmony_ci 149753a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_iter_next(&dict_entry_iter)); 149853a5a1b3Sopenharmony_ci dbus_message_iter_get_basic(&dict_entry_iter, &value); 149953a5a1b3Sopenharmony_ci 150053a5a1b3Sopenharmony_ci escaped_value = pa_escape(value, "\""); 150153a5a1b3Sopenharmony_ci pa_strbuf_printf(arg_buffer, "%s=\"%s\"", key, escaped_value); 150253a5a1b3Sopenharmony_ci pa_xfree(escaped_value); 150353a5a1b3Sopenharmony_ci 150453a5a1b3Sopenharmony_ci dbus_message_iter_next(&dict_iter); 150553a5a1b3Sopenharmony_ci } 150653a5a1b3Sopenharmony_ci 150753a5a1b3Sopenharmony_ci arg_string = pa_strbuf_to_string(arg_buffer); 150853a5a1b3Sopenharmony_ci 150953a5a1b3Sopenharmony_ci if (pa_module_load(&module, c->core, name, arg_string) < 0) { 151053a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Failed to load module."); 151153a5a1b3Sopenharmony_ci goto finish; 151253a5a1b3Sopenharmony_ci } 151353a5a1b3Sopenharmony_ci 151453a5a1b3Sopenharmony_ci /* This is created during module loading in module_new_cb() */ 151553a5a1b3Sopenharmony_ci dbus_module = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(module->index)); 151653a5a1b3Sopenharmony_ci object_path = pa_dbusiface_module_get_path(dbus_module); 151753a5a1b3Sopenharmony_ci 151853a5a1b3Sopenharmony_ci pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); 151953a5a1b3Sopenharmony_ci 152053a5a1b3Sopenharmony_cifinish: 152153a5a1b3Sopenharmony_ci if (arg_buffer) 152253a5a1b3Sopenharmony_ci pa_strbuf_free(arg_buffer); 152353a5a1b3Sopenharmony_ci 152453a5a1b3Sopenharmony_ci pa_xfree(arg_string); 152553a5a1b3Sopenharmony_ci} 152653a5a1b3Sopenharmony_ci 152753a5a1b3Sopenharmony_cistatic void handle_exit(DBusConnection *conn, DBusMessage *msg, void *userdata) { 152853a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 152953a5a1b3Sopenharmony_ci 153053a5a1b3Sopenharmony_ci pa_assert(conn); 153153a5a1b3Sopenharmony_ci pa_assert(msg); 153253a5a1b3Sopenharmony_ci pa_assert(c); 153353a5a1b3Sopenharmony_ci 153453a5a1b3Sopenharmony_ci if (c->core->disallow_exit) { 153553a5a1b3Sopenharmony_ci pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "The server is configured to disallow exiting."); 153653a5a1b3Sopenharmony_ci return; 153753a5a1b3Sopenharmony_ci } 153853a5a1b3Sopenharmony_ci 153953a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 154053a5a1b3Sopenharmony_ci 154153a5a1b3Sopenharmony_ci pa_core_exit(c->core, false, 0); 154253a5a1b3Sopenharmony_ci} 154353a5a1b3Sopenharmony_ci 154453a5a1b3Sopenharmony_cistatic void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) { 154553a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 154653a5a1b3Sopenharmony_ci const char *signal_str; 154753a5a1b3Sopenharmony_ci char **objects = NULL; 154853a5a1b3Sopenharmony_ci int n_objects; 154953a5a1b3Sopenharmony_ci 155053a5a1b3Sopenharmony_ci pa_assert(conn); 155153a5a1b3Sopenharmony_ci pa_assert(msg); 155253a5a1b3Sopenharmony_ci pa_assert(c); 155353a5a1b3Sopenharmony_ci 155453a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_get_args(msg, NULL, 155553a5a1b3Sopenharmony_ci DBUS_TYPE_STRING, &signal_str, 155653a5a1b3Sopenharmony_ci DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects, 155753a5a1b3Sopenharmony_ci DBUS_TYPE_INVALID)); 155853a5a1b3Sopenharmony_ci 155953a5a1b3Sopenharmony_ci pa_dbus_protocol_add_signal_listener(c->dbus_protocol, conn, *signal_str ? signal_str : NULL, objects, n_objects); 156053a5a1b3Sopenharmony_ci 156153a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 156253a5a1b3Sopenharmony_ci 156353a5a1b3Sopenharmony_ci dbus_free_string_array(objects); 156453a5a1b3Sopenharmony_ci} 156553a5a1b3Sopenharmony_ci 156653a5a1b3Sopenharmony_cistatic void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) { 156753a5a1b3Sopenharmony_ci pa_dbusiface_core *c = userdata; 156853a5a1b3Sopenharmony_ci const char *signal_str; 156953a5a1b3Sopenharmony_ci 157053a5a1b3Sopenharmony_ci pa_assert(conn); 157153a5a1b3Sopenharmony_ci pa_assert(msg); 157253a5a1b3Sopenharmony_ci pa_assert(c); 157353a5a1b3Sopenharmony_ci 157453a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &signal_str, DBUS_TYPE_INVALID)); 157553a5a1b3Sopenharmony_ci 157653a5a1b3Sopenharmony_ci pa_dbus_protocol_remove_signal_listener(c->dbus_protocol, conn, *signal_str ? signal_str : NULL); 157753a5a1b3Sopenharmony_ci 157853a5a1b3Sopenharmony_ci pa_dbus_send_empty_reply(conn, msg); 157953a5a1b3Sopenharmony_ci} 158053a5a1b3Sopenharmony_ci 158153a5a1b3Sopenharmony_cistatic pa_hook_result_t module_new_cb(void *hook_data, void *call_data, void *slot_data) { 158253a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 158353a5a1b3Sopenharmony_ci pa_module * module = call_data; 158453a5a1b3Sopenharmony_ci pa_dbusiface_module *module_iface; 158553a5a1b3Sopenharmony_ci const char *object_path; 158653a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 158753a5a1b3Sopenharmony_ci 158853a5a1b3Sopenharmony_ci pa_assert(c); 158953a5a1b3Sopenharmony_ci pa_assert(module); 159053a5a1b3Sopenharmony_ci 159153a5a1b3Sopenharmony_ci if (pa_streq(module->name, "module-dbus-protocol")) { 159253a5a1b3Sopenharmony_ci /* module-dbus-protocol can only be loaded once, and will be accounted 159353a5a1b3Sopenharmony_ci * for while iterating core->modules in pa_dbusiface_core_new(). As it 159453a5a1b3Sopenharmony_ci * happens, we will also see it here when the hook is called after the 159553a5a1b3Sopenharmony_ci * module is initialised, so we ignore it. */ 159653a5a1b3Sopenharmony_ci return PA_HOOK_OK; 159753a5a1b3Sopenharmony_ci } 159853a5a1b3Sopenharmony_ci 159953a5a1b3Sopenharmony_ci module_iface = pa_dbusiface_module_new(module); 160053a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(module->index), module_iface) >= 0); 160153a5a1b3Sopenharmony_ci 160253a5a1b3Sopenharmony_ci object_path = pa_dbusiface_module_get_path(module_iface); 160353a5a1b3Sopenharmony_ci 160453a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 160553a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 160653a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_MODULE].name))); 160753a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 160853a5a1b3Sopenharmony_ci 160953a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 161053a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 161153a5a1b3Sopenharmony_ci 161253a5a1b3Sopenharmony_ci return PA_HOOK_OK; 161353a5a1b3Sopenharmony_ci} 161453a5a1b3Sopenharmony_ci 161553a5a1b3Sopenharmony_cistatic pa_hook_result_t module_removed_cb(void *hook_data, void *call_data, void *slot_data) { 161653a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 161753a5a1b3Sopenharmony_ci pa_module * module = call_data; 161853a5a1b3Sopenharmony_ci pa_dbusiface_module *module_iface; 161953a5a1b3Sopenharmony_ci const char *object_path; 162053a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 162153a5a1b3Sopenharmony_ci 162253a5a1b3Sopenharmony_ci pa_assert(c); 162353a5a1b3Sopenharmony_ci pa_assert(module); 162453a5a1b3Sopenharmony_ci 162553a5a1b3Sopenharmony_ci pa_assert_se((module_iface = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(module->index)))); 162653a5a1b3Sopenharmony_ci 162753a5a1b3Sopenharmony_ci object_path = pa_dbusiface_module_get_path(module_iface); 162853a5a1b3Sopenharmony_ci 162953a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 163053a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 163153a5a1b3Sopenharmony_ci signals[SIGNAL_MODULE_REMOVED].name))); 163253a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 163353a5a1b3Sopenharmony_ci 163453a5a1b3Sopenharmony_ci pa_dbusiface_module_free(module_iface); 163553a5a1b3Sopenharmony_ci 163653a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 163753a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 163853a5a1b3Sopenharmony_ci 163953a5a1b3Sopenharmony_ci return PA_HOOK_OK; 164053a5a1b3Sopenharmony_ci} 164153a5a1b3Sopenharmony_ci 164253a5a1b3Sopenharmony_cistatic pa_hook_result_t sample_cache_new_cb(void *hook_data, void *call_data, void *slot_data) { 164353a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 164453a5a1b3Sopenharmony_ci pa_scache_entry *sample = call_data; 164553a5a1b3Sopenharmony_ci pa_dbusiface_sample *sample_iface; 164653a5a1b3Sopenharmony_ci const char *object_path; 164753a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 164853a5a1b3Sopenharmony_ci 164953a5a1b3Sopenharmony_ci pa_assert(c); 165053a5a1b3Sopenharmony_ci pa_assert(sample); 165153a5a1b3Sopenharmony_ci 165253a5a1b3Sopenharmony_ci sample_iface = pa_dbusiface_sample_new(c, sample); 165353a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(sample->index), sample_iface) >= 0); 165453a5a1b3Sopenharmony_ci 165553a5a1b3Sopenharmony_ci object_path = pa_dbusiface_sample_get_path(sample_iface); 165653a5a1b3Sopenharmony_ci 165753a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 165853a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 165953a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_SAMPLE].name))); 166053a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 166153a5a1b3Sopenharmony_ci 166253a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 166353a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 166453a5a1b3Sopenharmony_ci 166553a5a1b3Sopenharmony_ci return PA_HOOK_OK; 166653a5a1b3Sopenharmony_ci} 166753a5a1b3Sopenharmony_ci 166853a5a1b3Sopenharmony_cistatic pa_hook_result_t sample_cache_removed_cb(void *hook_data, void *call_data, void *slot_data) { 166953a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 167053a5a1b3Sopenharmony_ci pa_scache_entry *sample = call_data; 167153a5a1b3Sopenharmony_ci pa_dbusiface_sample *sample_iface; 167253a5a1b3Sopenharmony_ci const char *object_path; 167353a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 167453a5a1b3Sopenharmony_ci 167553a5a1b3Sopenharmony_ci pa_assert(c); 167653a5a1b3Sopenharmony_ci pa_assert(sample); 167753a5a1b3Sopenharmony_ci 167853a5a1b3Sopenharmony_ci pa_assert_se((sample_iface = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(sample->index)))); 167953a5a1b3Sopenharmony_ci 168053a5a1b3Sopenharmony_ci object_path = pa_dbusiface_sample_get_path(sample_iface); 168153a5a1b3Sopenharmony_ci 168253a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 168353a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 168453a5a1b3Sopenharmony_ci signals[SIGNAL_SAMPLE_REMOVED].name))); 168553a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 168653a5a1b3Sopenharmony_ci 168753a5a1b3Sopenharmony_ci pa_dbusiface_sample_free(sample_iface); 168853a5a1b3Sopenharmony_ci 168953a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 169053a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 169153a5a1b3Sopenharmony_ci 169253a5a1b3Sopenharmony_ci return PA_HOOK_OK; 169353a5a1b3Sopenharmony_ci} 169453a5a1b3Sopenharmony_ci 169553a5a1b3Sopenharmony_cistatic pa_dbusiface_device *create_dbus_object_for_sink(pa_dbusiface_core *c, pa_sink *s) { 169653a5a1b3Sopenharmony_ci pa_dbusiface_device *d; 169753a5a1b3Sopenharmony_ci const char *object_path; 169853a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 169953a5a1b3Sopenharmony_ci 170053a5a1b3Sopenharmony_ci d = pa_dbusiface_device_new_sink(c, s); 170153a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(d); 170253a5a1b3Sopenharmony_ci 170353a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0); 170453a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->sinks_by_path, (char *) object_path, d) >= 0); 170553a5a1b3Sopenharmony_ci 170653a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 170753a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 170853a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_SINK].name))); 170953a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 171053a5a1b3Sopenharmony_ci 171153a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 171253a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 171353a5a1b3Sopenharmony_ci 171453a5a1b3Sopenharmony_ci return d; 171553a5a1b3Sopenharmony_ci} 171653a5a1b3Sopenharmony_ci 171753a5a1b3Sopenharmony_cistatic pa_hook_result_t default_sink_changed_cb(void *hook_data, void *call_data, void *slot_data) { 171853a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 171953a5a1b3Sopenharmony_ci pa_sink *new_fallback_sink = call_data; 172053a5a1b3Sopenharmony_ci pa_dbusiface_device *device_iface; 172153a5a1b3Sopenharmony_ci const char *object_path; 172253a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 172353a5a1b3Sopenharmony_ci 172453a5a1b3Sopenharmony_ci pa_assert(c); 172553a5a1b3Sopenharmony_ci 172653a5a1b3Sopenharmony_ci if (c->fallback_sink != new_fallback_sink) { 172753a5a1b3Sopenharmony_ci if (c->fallback_sink) 172853a5a1b3Sopenharmony_ci pa_sink_unref(c->fallback_sink); 172953a5a1b3Sopenharmony_ci c->fallback_sink = new_fallback_sink ? pa_sink_ref(new_fallback_sink) : NULL; 173053a5a1b3Sopenharmony_ci 173153a5a1b3Sopenharmony_ci if (c->fallback_sink) { 173253a5a1b3Sopenharmony_ci device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)); 173353a5a1b3Sopenharmony_ci 173453a5a1b3Sopenharmony_ci /* It's possible that we haven't created a dbus object for the 173553a5a1b3Sopenharmony_ci * source yet, because if a new source immediately becomes the 173653a5a1b3Sopenharmony_ci * default source, the default source change hook is fired before 173753a5a1b3Sopenharmony_ci * the put hook. */ 173853a5a1b3Sopenharmony_ci if (!device_iface) 173953a5a1b3Sopenharmony_ci device_iface = create_dbus_object_for_sink(c, c->fallback_sink); 174053a5a1b3Sopenharmony_ci 174153a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(device_iface); 174253a5a1b3Sopenharmony_ci 174353a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 174453a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 174553a5a1b3Sopenharmony_ci signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); 174653a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 174753a5a1b3Sopenharmony_ci 174853a5a1b3Sopenharmony_ci } else { 174953a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 175053a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 175153a5a1b3Sopenharmony_ci signals[SIGNAL_FALLBACK_SINK_UNSET].name))); 175253a5a1b3Sopenharmony_ci } 175353a5a1b3Sopenharmony_ci } 175453a5a1b3Sopenharmony_ci 175553a5a1b3Sopenharmony_ci if (signal_msg) { 175653a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 175753a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 175853a5a1b3Sopenharmony_ci } 175953a5a1b3Sopenharmony_ci 176053a5a1b3Sopenharmony_ci return PA_HOOK_OK; 176153a5a1b3Sopenharmony_ci} 176253a5a1b3Sopenharmony_ci 176353a5a1b3Sopenharmony_cistatic pa_dbusiface_device *create_dbus_object_for_source(pa_dbusiface_core *c, pa_source *s) { 176453a5a1b3Sopenharmony_ci pa_dbusiface_device *d; 176553a5a1b3Sopenharmony_ci const char *object_path; 176653a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 176753a5a1b3Sopenharmony_ci 176853a5a1b3Sopenharmony_ci d = pa_dbusiface_device_new_source(c, s); 176953a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(d); 177053a5a1b3Sopenharmony_ci 177153a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0); 177253a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->sources_by_path, (char *) object_path, d) >= 0); 177353a5a1b3Sopenharmony_ci 177453a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 177553a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 177653a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_SOURCE].name))); 177753a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 177853a5a1b3Sopenharmony_ci 177953a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 178053a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 178153a5a1b3Sopenharmony_ci 178253a5a1b3Sopenharmony_ci return d; 178353a5a1b3Sopenharmony_ci} 178453a5a1b3Sopenharmony_ci 178553a5a1b3Sopenharmony_cistatic pa_hook_result_t default_source_changed_cb(void *hook_data, void *call_data, void *slot_data) { 178653a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 178753a5a1b3Sopenharmony_ci pa_source *new_fallback_source = call_data; 178853a5a1b3Sopenharmony_ci pa_dbusiface_device *device_iface; 178953a5a1b3Sopenharmony_ci const char *object_path; 179053a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 179153a5a1b3Sopenharmony_ci 179253a5a1b3Sopenharmony_ci pa_assert(c); 179353a5a1b3Sopenharmony_ci 179453a5a1b3Sopenharmony_ci if (c->fallback_source != new_fallback_source) { 179553a5a1b3Sopenharmony_ci if (c->fallback_source) 179653a5a1b3Sopenharmony_ci pa_source_unref(c->fallback_source); 179753a5a1b3Sopenharmony_ci c->fallback_source = new_fallback_source ? pa_source_ref(new_fallback_source) : NULL; 179853a5a1b3Sopenharmony_ci 179953a5a1b3Sopenharmony_ci if (c->fallback_source) { 180053a5a1b3Sopenharmony_ci device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index)); 180153a5a1b3Sopenharmony_ci 180253a5a1b3Sopenharmony_ci /* It's possible that we haven't created a dbus object for the 180353a5a1b3Sopenharmony_ci * source yet, because if a new source immediately becomes the 180453a5a1b3Sopenharmony_ci * default source, the default source change hook is fired before 180553a5a1b3Sopenharmony_ci * the put hook. */ 180653a5a1b3Sopenharmony_ci if (!device_iface) 180753a5a1b3Sopenharmony_ci device_iface = create_dbus_object_for_source(c, c->fallback_source); 180853a5a1b3Sopenharmony_ci 180953a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(device_iface); 181053a5a1b3Sopenharmony_ci 181153a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 181253a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 181353a5a1b3Sopenharmony_ci signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); 181453a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 181553a5a1b3Sopenharmony_ci 181653a5a1b3Sopenharmony_ci } else { 181753a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 181853a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 181953a5a1b3Sopenharmony_ci signals[SIGNAL_FALLBACK_SOURCE_UNSET].name))); 182053a5a1b3Sopenharmony_ci } 182153a5a1b3Sopenharmony_ci } 182253a5a1b3Sopenharmony_ci 182353a5a1b3Sopenharmony_ci if (signal_msg) { 182453a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 182553a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 182653a5a1b3Sopenharmony_ci } 182753a5a1b3Sopenharmony_ci 182853a5a1b3Sopenharmony_ci return PA_HOOK_OK; 182953a5a1b3Sopenharmony_ci} 183053a5a1b3Sopenharmony_ci 183153a5a1b3Sopenharmony_cistatic pa_hook_result_t card_put_cb(void *hook_data, void *call_data, void *slot_data) { 183253a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 183353a5a1b3Sopenharmony_ci pa_card *card = call_data; 183453a5a1b3Sopenharmony_ci pa_dbusiface_card *card_iface = NULL; 183553a5a1b3Sopenharmony_ci const char *object_path; 183653a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 183753a5a1b3Sopenharmony_ci 183853a5a1b3Sopenharmony_ci pa_assert(c); 183953a5a1b3Sopenharmony_ci pa_assert(card); 184053a5a1b3Sopenharmony_ci 184153a5a1b3Sopenharmony_ci card_iface = pa_dbusiface_card_new(c, card); 184253a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(card->index), card_iface) >= 0); 184353a5a1b3Sopenharmony_ci 184453a5a1b3Sopenharmony_ci object_path = pa_dbusiface_card_get_path(card_iface); 184553a5a1b3Sopenharmony_ci 184653a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 184753a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 184853a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_CARD].name))); 184953a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 185053a5a1b3Sopenharmony_ci 185153a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 185253a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 185353a5a1b3Sopenharmony_ci 185453a5a1b3Sopenharmony_ci return PA_HOOK_OK; 185553a5a1b3Sopenharmony_ci} 185653a5a1b3Sopenharmony_ci 185753a5a1b3Sopenharmony_cistatic pa_hook_result_t card_unlink_cb(void *hook_data, void *call_data, void *slot_data) { 185853a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 185953a5a1b3Sopenharmony_ci pa_card *card = call_data; 186053a5a1b3Sopenharmony_ci pa_dbusiface_card *card_iface; 186153a5a1b3Sopenharmony_ci const char *object_path; 186253a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 186353a5a1b3Sopenharmony_ci 186453a5a1b3Sopenharmony_ci pa_assert(c); 186553a5a1b3Sopenharmony_ci pa_assert(card); 186653a5a1b3Sopenharmony_ci 186753a5a1b3Sopenharmony_ci pa_assert_se((card_iface = pa_hashmap_remove(c->cards, PA_UINT32_TO_PTR(card->index)))); 186853a5a1b3Sopenharmony_ci 186953a5a1b3Sopenharmony_ci object_path = pa_dbusiface_card_get_path(card_iface); 187053a5a1b3Sopenharmony_ci 187153a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 187253a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 187353a5a1b3Sopenharmony_ci signals[SIGNAL_CARD_REMOVED].name))); 187453a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 187553a5a1b3Sopenharmony_ci 187653a5a1b3Sopenharmony_ci pa_dbusiface_card_free(card_iface); 187753a5a1b3Sopenharmony_ci 187853a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 187953a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 188053a5a1b3Sopenharmony_ci 188153a5a1b3Sopenharmony_ci return PA_HOOK_OK; 188253a5a1b3Sopenharmony_ci} 188353a5a1b3Sopenharmony_ci 188453a5a1b3Sopenharmony_cistatic pa_hook_result_t sink_input_put_cb(void *hook_data, void *call_data, void *slot_data) { 188553a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 188653a5a1b3Sopenharmony_ci pa_sink_input *sink_input = call_data; 188753a5a1b3Sopenharmony_ci pa_dbusiface_stream *stream_iface; 188853a5a1b3Sopenharmony_ci const char *object_path; 188953a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 189053a5a1b3Sopenharmony_ci 189153a5a1b3Sopenharmony_ci pa_assert(c); 189253a5a1b3Sopenharmony_ci pa_assert(sink_input); 189353a5a1b3Sopenharmony_ci 189453a5a1b3Sopenharmony_ci stream_iface = pa_dbusiface_stream_new_playback(c, sink_input); 189553a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(sink_input->index), stream_iface) >= 0); 189653a5a1b3Sopenharmony_ci 189753a5a1b3Sopenharmony_ci object_path = pa_dbusiface_stream_get_path(stream_iface); 189853a5a1b3Sopenharmony_ci 189953a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 190053a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 190153a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); 190253a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 190353a5a1b3Sopenharmony_ci 190453a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 190553a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 190653a5a1b3Sopenharmony_ci 190753a5a1b3Sopenharmony_ci return PA_HOOK_OK; 190853a5a1b3Sopenharmony_ci} 190953a5a1b3Sopenharmony_ci 191053a5a1b3Sopenharmony_cistatic pa_hook_result_t sink_input_unlink_cb(void *hook_data, void *call_data, void *slot_data) { 191153a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 191253a5a1b3Sopenharmony_ci pa_sink_input *sink_input = call_data; 191353a5a1b3Sopenharmony_ci pa_dbusiface_stream *stream_iface; 191453a5a1b3Sopenharmony_ci const char *object_path; 191553a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 191653a5a1b3Sopenharmony_ci 191753a5a1b3Sopenharmony_ci pa_assert(c); 191853a5a1b3Sopenharmony_ci pa_assert(sink_input); 191953a5a1b3Sopenharmony_ci 192053a5a1b3Sopenharmony_ci pa_assert_se((stream_iface = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(sink_input->index)))); 192153a5a1b3Sopenharmony_ci 192253a5a1b3Sopenharmony_ci object_path = pa_dbusiface_stream_get_path(stream_iface); 192353a5a1b3Sopenharmony_ci 192453a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 192553a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 192653a5a1b3Sopenharmony_ci signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); 192753a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 192853a5a1b3Sopenharmony_ci 192953a5a1b3Sopenharmony_ci pa_dbusiface_stream_free(stream_iface); 193053a5a1b3Sopenharmony_ci 193153a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 193253a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 193353a5a1b3Sopenharmony_ci 193453a5a1b3Sopenharmony_ci return PA_HOOK_OK; 193553a5a1b3Sopenharmony_ci} 193653a5a1b3Sopenharmony_ci 193753a5a1b3Sopenharmony_cistatic pa_hook_result_t source_output_put_cb(void *hook_data, void *call_data, void *slot_data) { 193853a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 193953a5a1b3Sopenharmony_ci pa_source_output *source_output = call_data; 194053a5a1b3Sopenharmony_ci pa_dbusiface_stream *stream_iface; 194153a5a1b3Sopenharmony_ci const char *object_path; 194253a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 194353a5a1b3Sopenharmony_ci 194453a5a1b3Sopenharmony_ci pa_assert(c); 194553a5a1b3Sopenharmony_ci pa_assert(source_output); 194653a5a1b3Sopenharmony_ci 194753a5a1b3Sopenharmony_ci stream_iface = pa_dbusiface_stream_new_record(c, source_output); 194853a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(source_output->index), stream_iface) >= 0); 194953a5a1b3Sopenharmony_ci 195053a5a1b3Sopenharmony_ci object_path = pa_dbusiface_stream_get_path(stream_iface); 195153a5a1b3Sopenharmony_ci 195253a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 195353a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 195453a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_RECORD_STREAM].name))); 195553a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 195653a5a1b3Sopenharmony_ci 195753a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 195853a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 195953a5a1b3Sopenharmony_ci 196053a5a1b3Sopenharmony_ci return PA_HOOK_OK; 196153a5a1b3Sopenharmony_ci} 196253a5a1b3Sopenharmony_ci 196353a5a1b3Sopenharmony_cistatic pa_hook_result_t source_output_unlink_cb(void *hook_data, void *call_data, void *slot_data) { 196453a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 196553a5a1b3Sopenharmony_ci pa_source_output *source_output = call_data; 196653a5a1b3Sopenharmony_ci pa_dbusiface_stream *stream_iface; 196753a5a1b3Sopenharmony_ci const char *object_path; 196853a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 196953a5a1b3Sopenharmony_ci 197053a5a1b3Sopenharmony_ci pa_assert(c); 197153a5a1b3Sopenharmony_ci pa_assert(source_output); 197253a5a1b3Sopenharmony_ci 197353a5a1b3Sopenharmony_ci pa_assert_se((stream_iface = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(source_output->index)))); 197453a5a1b3Sopenharmony_ci 197553a5a1b3Sopenharmony_ci object_path = pa_dbusiface_stream_get_path(stream_iface); 197653a5a1b3Sopenharmony_ci 197753a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 197853a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 197953a5a1b3Sopenharmony_ci signals[SIGNAL_RECORD_STREAM_REMOVED].name))); 198053a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 198153a5a1b3Sopenharmony_ci 198253a5a1b3Sopenharmony_ci pa_dbusiface_stream_free(stream_iface); 198353a5a1b3Sopenharmony_ci 198453a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 198553a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 198653a5a1b3Sopenharmony_ci 198753a5a1b3Sopenharmony_ci return PA_HOOK_OK; 198853a5a1b3Sopenharmony_ci} 198953a5a1b3Sopenharmony_ci 199053a5a1b3Sopenharmony_cistatic pa_hook_result_t client_put_cb(void *hook_data, void *call_data, void *slot_data) { 199153a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 199253a5a1b3Sopenharmony_ci pa_client *client = call_data; 199353a5a1b3Sopenharmony_ci pa_dbusiface_client *client_iface; 199453a5a1b3Sopenharmony_ci const char *object_path; 199553a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 199653a5a1b3Sopenharmony_ci 199753a5a1b3Sopenharmony_ci pa_assert(c); 199853a5a1b3Sopenharmony_ci pa_assert(client); 199953a5a1b3Sopenharmony_ci 200053a5a1b3Sopenharmony_ci client_iface = pa_dbusiface_client_new(c, client); 200153a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(client->index), client_iface) >= 0); 200253a5a1b3Sopenharmony_ci 200353a5a1b3Sopenharmony_ci object_path = pa_dbusiface_client_get_path(client_iface); 200453a5a1b3Sopenharmony_ci 200553a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 200653a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 200753a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_CLIENT].name))); 200853a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 200953a5a1b3Sopenharmony_ci 201053a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 201153a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 201253a5a1b3Sopenharmony_ci 201353a5a1b3Sopenharmony_ci return PA_HOOK_OK; 201453a5a1b3Sopenharmony_ci} 201553a5a1b3Sopenharmony_ci 201653a5a1b3Sopenharmony_cistatic pa_hook_result_t client_unlink_cb(void *hook_data, void *call_data, void *slot_data) { 201753a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 201853a5a1b3Sopenharmony_ci pa_client *client = call_data; 201953a5a1b3Sopenharmony_ci pa_dbusiface_client *client_iface; 202053a5a1b3Sopenharmony_ci const char *object_path; 202153a5a1b3Sopenharmony_ci DBusMessage *signal_msg; 202253a5a1b3Sopenharmony_ci 202353a5a1b3Sopenharmony_ci pa_assert(c); 202453a5a1b3Sopenharmony_ci pa_assert(client); 202553a5a1b3Sopenharmony_ci 202653a5a1b3Sopenharmony_ci pa_assert_se((client_iface = pa_hashmap_remove(c->clients, PA_UINT32_TO_PTR(client->index)))); 202753a5a1b3Sopenharmony_ci 202853a5a1b3Sopenharmony_ci object_path = pa_dbusiface_client_get_path(client_iface); 202953a5a1b3Sopenharmony_ci 203053a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 203153a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 203253a5a1b3Sopenharmony_ci signals[SIGNAL_CLIENT_REMOVED].name))); 203353a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 203453a5a1b3Sopenharmony_ci 203553a5a1b3Sopenharmony_ci pa_dbusiface_client_free(client_iface); 203653a5a1b3Sopenharmony_ci 203753a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 203853a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 203953a5a1b3Sopenharmony_ci 204053a5a1b3Sopenharmony_ci return PA_HOOK_OK; 204153a5a1b3Sopenharmony_ci} 204253a5a1b3Sopenharmony_ci 204353a5a1b3Sopenharmony_cistatic pa_hook_result_t sink_put_cb(void *hook_data, void *call_data, void *slot_data) { 204453a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 204553a5a1b3Sopenharmony_ci pa_sink *s = call_data; 204653a5a1b3Sopenharmony_ci 204753a5a1b3Sopenharmony_ci pa_assert(c); 204853a5a1b3Sopenharmony_ci pa_assert(s); 204953a5a1b3Sopenharmony_ci 205053a5a1b3Sopenharmony_ci /* We may have alredy encountered this sink, because if the new sink was 205153a5a1b3Sopenharmony_ci * chosen as the default sink, the default sink change hook was fired 205253a5a1b3Sopenharmony_ci * first, and we saw the sink in default_sink_changed_cb(). */ 205353a5a1b3Sopenharmony_ci if (pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(s->index))) 205453a5a1b3Sopenharmony_ci return PA_HOOK_OK; 205553a5a1b3Sopenharmony_ci 205653a5a1b3Sopenharmony_ci create_dbus_object_for_sink(c, s); 205753a5a1b3Sopenharmony_ci 205853a5a1b3Sopenharmony_ci return PA_HOOK_OK; 205953a5a1b3Sopenharmony_ci} 206053a5a1b3Sopenharmony_ci 206153a5a1b3Sopenharmony_cistatic pa_hook_result_t sink_unlink_cb(void *hook_data, void *call_data, void *slot_data) { 206253a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 206353a5a1b3Sopenharmony_ci pa_sink *s = call_data; 206453a5a1b3Sopenharmony_ci pa_dbusiface_device *d = NULL; 206553a5a1b3Sopenharmony_ci const char *object_path = NULL; 206653a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 206753a5a1b3Sopenharmony_ci 206853a5a1b3Sopenharmony_ci pa_assert(c); 206953a5a1b3Sopenharmony_ci pa_assert(s); 207053a5a1b3Sopenharmony_ci 207153a5a1b3Sopenharmony_ci pa_assert_se(d = pa_hashmap_remove(c->sinks_by_index, PA_UINT32_TO_PTR(s->index))); 207253a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(d); 207353a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path)); 207453a5a1b3Sopenharmony_ci 207553a5a1b3Sopenharmony_ci pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 207653a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 207753a5a1b3Sopenharmony_ci signals[SIGNAL_SINK_REMOVED].name)); 207853a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 207953a5a1b3Sopenharmony_ci 208053a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 208153a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 208253a5a1b3Sopenharmony_ci 208353a5a1b3Sopenharmony_ci pa_dbusiface_device_free(d); 208453a5a1b3Sopenharmony_ci 208553a5a1b3Sopenharmony_ci return PA_HOOK_OK; 208653a5a1b3Sopenharmony_ci} 208753a5a1b3Sopenharmony_ci 208853a5a1b3Sopenharmony_cistatic pa_hook_result_t source_put_cb(void *hook_data, void *call_data, void *slot_data) { 208953a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 209053a5a1b3Sopenharmony_ci pa_source *s = call_data; 209153a5a1b3Sopenharmony_ci 209253a5a1b3Sopenharmony_ci pa_assert(c); 209353a5a1b3Sopenharmony_ci pa_assert(s); 209453a5a1b3Sopenharmony_ci 209553a5a1b3Sopenharmony_ci /* We may have alredy encountered this source, because if the new source 209653a5a1b3Sopenharmony_ci * was chosen as the default source, the default source change hook was 209753a5a1b3Sopenharmony_ci * fired first, and we saw the source in default_source_changed_cb(). */ 209853a5a1b3Sopenharmony_ci if (pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(s->index))) 209953a5a1b3Sopenharmony_ci return PA_HOOK_OK; 210053a5a1b3Sopenharmony_ci 210153a5a1b3Sopenharmony_ci create_dbus_object_for_source(c, s); 210253a5a1b3Sopenharmony_ci 210353a5a1b3Sopenharmony_ci return PA_HOOK_OK; 210453a5a1b3Sopenharmony_ci} 210553a5a1b3Sopenharmony_ci 210653a5a1b3Sopenharmony_cistatic pa_hook_result_t source_unlink_cb(void *hook_data, void *call_data, void *slot_data) { 210753a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 210853a5a1b3Sopenharmony_ci pa_source *s = call_data; 210953a5a1b3Sopenharmony_ci pa_dbusiface_device *d = NULL; 211053a5a1b3Sopenharmony_ci const char *object_path = NULL; 211153a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 211253a5a1b3Sopenharmony_ci 211353a5a1b3Sopenharmony_ci pa_assert(c); 211453a5a1b3Sopenharmony_ci pa_assert(s); 211553a5a1b3Sopenharmony_ci 211653a5a1b3Sopenharmony_ci pa_assert_se(d = pa_hashmap_remove(c->sources_by_index, PA_UINT32_TO_PTR(s->index))); 211753a5a1b3Sopenharmony_ci object_path = pa_dbusiface_device_get_path(d); 211853a5a1b3Sopenharmony_ci pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path)); 211953a5a1b3Sopenharmony_ci 212053a5a1b3Sopenharmony_ci pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 212153a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 212253a5a1b3Sopenharmony_ci signals[SIGNAL_SOURCE_REMOVED].name)); 212353a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); 212453a5a1b3Sopenharmony_ci 212553a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 212653a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 212753a5a1b3Sopenharmony_ci 212853a5a1b3Sopenharmony_ci pa_dbusiface_device_free(d); 212953a5a1b3Sopenharmony_ci 213053a5a1b3Sopenharmony_ci return PA_HOOK_OK; 213153a5a1b3Sopenharmony_ci} 213253a5a1b3Sopenharmony_ci 213353a5a1b3Sopenharmony_cistatic pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data, void *slot_data) { 213453a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 213553a5a1b3Sopenharmony_ci const char *ext_name = call_data; 213653a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 213753a5a1b3Sopenharmony_ci 213853a5a1b3Sopenharmony_ci pa_assert(c); 213953a5a1b3Sopenharmony_ci pa_assert(ext_name); 214053a5a1b3Sopenharmony_ci 214153a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 214253a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 214353a5a1b3Sopenharmony_ci signals[SIGNAL_NEW_EXTENSION].name))); 214453a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); 214553a5a1b3Sopenharmony_ci 214653a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 214753a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 214853a5a1b3Sopenharmony_ci 214953a5a1b3Sopenharmony_ci return PA_HOOK_OK; 215053a5a1b3Sopenharmony_ci} 215153a5a1b3Sopenharmony_ci 215253a5a1b3Sopenharmony_cistatic pa_hook_result_t extension_unregistered_cb(void *hook_data, void *call_data, void *slot_data) { 215353a5a1b3Sopenharmony_ci pa_dbusiface_core *c = slot_data; 215453a5a1b3Sopenharmony_ci const char *ext_name = call_data; 215553a5a1b3Sopenharmony_ci DBusMessage *signal_msg = NULL; 215653a5a1b3Sopenharmony_ci 215753a5a1b3Sopenharmony_ci pa_assert(c); 215853a5a1b3Sopenharmony_ci pa_assert(ext_name); 215953a5a1b3Sopenharmony_ci 216053a5a1b3Sopenharmony_ci pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, 216153a5a1b3Sopenharmony_ci PA_DBUS_CORE_INTERFACE, 216253a5a1b3Sopenharmony_ci signals[SIGNAL_EXTENSION_REMOVED].name))); 216353a5a1b3Sopenharmony_ci pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); 216453a5a1b3Sopenharmony_ci 216553a5a1b3Sopenharmony_ci pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg); 216653a5a1b3Sopenharmony_ci dbus_message_unref(signal_msg); 216753a5a1b3Sopenharmony_ci 216853a5a1b3Sopenharmony_ci return PA_HOOK_OK; 216953a5a1b3Sopenharmony_ci} 217053a5a1b3Sopenharmony_ci 217153a5a1b3Sopenharmony_cipa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { 217253a5a1b3Sopenharmony_ci pa_dbusiface_core *c; 217353a5a1b3Sopenharmony_ci pa_card *card; 217453a5a1b3Sopenharmony_ci pa_sink *sink; 217553a5a1b3Sopenharmony_ci pa_source *source; 217653a5a1b3Sopenharmony_ci pa_dbusiface_device *device; 217753a5a1b3Sopenharmony_ci pa_sink_input *sink_input; 217853a5a1b3Sopenharmony_ci pa_source_output *source_output; 217953a5a1b3Sopenharmony_ci pa_scache_entry *sample; 218053a5a1b3Sopenharmony_ci pa_module *module; 218153a5a1b3Sopenharmony_ci pa_client *client; 218253a5a1b3Sopenharmony_ci uint32_t idx; 218353a5a1b3Sopenharmony_ci 218453a5a1b3Sopenharmony_ci pa_assert(core); 218553a5a1b3Sopenharmony_ci 218653a5a1b3Sopenharmony_ci c = pa_xnew(pa_dbusiface_core, 1); 218753a5a1b3Sopenharmony_ci c->core = core; 218853a5a1b3Sopenharmony_ci c->dbus_protocol = pa_dbus_protocol_get(core); 218953a5a1b3Sopenharmony_ci c->cards = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_card_free); 219053a5a1b3Sopenharmony_ci c->sinks_by_index = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, 219153a5a1b3Sopenharmony_ci (pa_free_cb_t) pa_dbusiface_device_free); 219253a5a1b3Sopenharmony_ci c->sinks_by_path = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); 219353a5a1b3Sopenharmony_ci c->sources_by_index = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, 219453a5a1b3Sopenharmony_ci (pa_free_cb_t) pa_dbusiface_device_free); 219553a5a1b3Sopenharmony_ci c->sources_by_path = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); 219653a5a1b3Sopenharmony_ci c->playback_streams = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, 219753a5a1b3Sopenharmony_ci (pa_free_cb_t) pa_dbusiface_stream_free); 219853a5a1b3Sopenharmony_ci c->record_streams = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, 219953a5a1b3Sopenharmony_ci (pa_free_cb_t) pa_dbusiface_stream_free); 220053a5a1b3Sopenharmony_ci c->samples = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_sample_free); 220153a5a1b3Sopenharmony_ci c->modules = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_module_free); 220253a5a1b3Sopenharmony_ci c->clients = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_client_free); 220353a5a1b3Sopenharmony_ci c->fallback_sink = core->default_sink; 220453a5a1b3Sopenharmony_ci c->fallback_source = core->default_source; 220553a5a1b3Sopenharmony_ci c->default_sink_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], 220653a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, default_sink_changed_cb, c); 220753a5a1b3Sopenharmony_ci c->default_source_changed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], 220853a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, default_source_changed_cb, c); 220953a5a1b3Sopenharmony_ci c->module_new_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_MODULE_NEW], 221053a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, module_new_cb, c); 221153a5a1b3Sopenharmony_ci c->module_removed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_MODULE_UNLINK], 221253a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, module_removed_cb, c); 221353a5a1b3Sopenharmony_ci c->sample_cache_new_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SAMPLE_CACHE_NEW], 221453a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, sample_cache_new_cb, c); 221553a5a1b3Sopenharmony_ci c->sample_cache_removed_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SAMPLE_CACHE_UNLINK], 221653a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, sample_cache_removed_cb, c); 221753a5a1b3Sopenharmony_ci c->card_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_CARD_PUT], 221853a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, card_put_cb, c); 221953a5a1b3Sopenharmony_ci c->card_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_CARD_UNLINK], 222053a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, card_unlink_cb, c); 222153a5a1b3Sopenharmony_ci c->sink_input_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], 222253a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, sink_input_put_cb, c); 222353a5a1b3Sopenharmony_ci c->sink_input_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], 222453a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, sink_input_unlink_cb, c); 222553a5a1b3Sopenharmony_ci c->source_output_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], 222653a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, source_output_put_cb, c); 222753a5a1b3Sopenharmony_ci c->source_output_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], 222853a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, source_output_unlink_cb, c); 222953a5a1b3Sopenharmony_ci c->client_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_CLIENT_PUT], 223053a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, client_put_cb, c); 223153a5a1b3Sopenharmony_ci c->client_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_CLIENT_UNLINK], 223253a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, client_unlink_cb, c); 223353a5a1b3Sopenharmony_ci c->sink_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL, sink_put_cb, c); 223453a5a1b3Sopenharmony_ci c->sink_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_NORMAL, sink_unlink_cb, c); 223553a5a1b3Sopenharmony_ci c->source_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL, source_put_cb, c); 223653a5a1b3Sopenharmony_ci c->source_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_NORMAL, source_unlink_cb, c); 223753a5a1b3Sopenharmony_ci c->extension_registered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, 223853a5a1b3Sopenharmony_ci PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED, 223953a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, 224053a5a1b3Sopenharmony_ci extension_registered_cb, 224153a5a1b3Sopenharmony_ci c); 224253a5a1b3Sopenharmony_ci c->extension_unregistered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, 224353a5a1b3Sopenharmony_ci PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED, 224453a5a1b3Sopenharmony_ci PA_HOOK_NORMAL, 224553a5a1b3Sopenharmony_ci extension_unregistered_cb, 224653a5a1b3Sopenharmony_ci c); 224753a5a1b3Sopenharmony_ci c->memstats = pa_dbusiface_memstats_new(c, core); 224853a5a1b3Sopenharmony_ci 224953a5a1b3Sopenharmony_ci if (c->fallback_sink) 225053a5a1b3Sopenharmony_ci pa_sink_ref(c->fallback_sink); 225153a5a1b3Sopenharmony_ci if (c->fallback_source) 225253a5a1b3Sopenharmony_ci pa_source_ref(c->fallback_source); 225353a5a1b3Sopenharmony_ci 225453a5a1b3Sopenharmony_ci PA_IDXSET_FOREACH(card, core->cards, idx) 225553a5a1b3Sopenharmony_ci pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(c, card)); 225653a5a1b3Sopenharmony_ci 225753a5a1b3Sopenharmony_ci PA_IDXSET_FOREACH(sink, core->sinks, idx) { 225853a5a1b3Sopenharmony_ci device = pa_dbusiface_device_new_sink(c, sink); 225953a5a1b3Sopenharmony_ci pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); 226053a5a1b3Sopenharmony_ci pa_hashmap_put(c->sinks_by_path, (char *) pa_dbusiface_device_get_path(device), device); 226153a5a1b3Sopenharmony_ci } 226253a5a1b3Sopenharmony_ci 226353a5a1b3Sopenharmony_ci PA_IDXSET_FOREACH(source, core->sources, idx) { 226453a5a1b3Sopenharmony_ci device = pa_dbusiface_device_new_source(c, source); 226553a5a1b3Sopenharmony_ci pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); 226653a5a1b3Sopenharmony_ci pa_hashmap_put(c->sources_by_path, (char *) pa_dbusiface_device_get_path(device), device); 226753a5a1b3Sopenharmony_ci } 226853a5a1b3Sopenharmony_ci 226953a5a1b3Sopenharmony_ci PA_IDXSET_FOREACH(sink_input, core->sink_inputs, idx) 227053a5a1b3Sopenharmony_ci pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_playback(c, sink_input)); 227153a5a1b3Sopenharmony_ci 227253a5a1b3Sopenharmony_ci PA_IDXSET_FOREACH(source_output, core->source_outputs, idx) 227353a5a1b3Sopenharmony_ci pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_record(c, source_output)); 227453a5a1b3Sopenharmony_ci 227553a5a1b3Sopenharmony_ci PA_IDXSET_FOREACH(sample, core->scache, idx) 227653a5a1b3Sopenharmony_ci pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), pa_dbusiface_sample_new(c, sample)); 227753a5a1b3Sopenharmony_ci 227853a5a1b3Sopenharmony_ci PA_IDXSET_FOREACH(module, core->modules, idx) 227953a5a1b3Sopenharmony_ci pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), pa_dbusiface_module_new(module)); 228053a5a1b3Sopenharmony_ci 228153a5a1b3Sopenharmony_ci PA_IDXSET_FOREACH(client, core->clients, idx) 228253a5a1b3Sopenharmony_ci pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), pa_dbusiface_client_new(c, client)); 228353a5a1b3Sopenharmony_ci 228453a5a1b3Sopenharmony_ci pa_assert_se(pa_dbus_protocol_add_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, &core_interface_info, c) >= 0); 228553a5a1b3Sopenharmony_ci 228653a5a1b3Sopenharmony_ci return c; 228753a5a1b3Sopenharmony_ci} 228853a5a1b3Sopenharmony_ci 228953a5a1b3Sopenharmony_civoid pa_dbusiface_core_free(pa_dbusiface_core *c) { 229053a5a1b3Sopenharmony_ci pa_assert(c); 229153a5a1b3Sopenharmony_ci 229253a5a1b3Sopenharmony_ci pa_assert_se(pa_dbus_protocol_remove_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, core_interface_info.name) >= 0); 229353a5a1b3Sopenharmony_ci 229453a5a1b3Sopenharmony_ci /* Note that the order of freeing is important below. 229553a5a1b3Sopenharmony_ci * Do not change it for the sake of tidiness without checking! */ 229653a5a1b3Sopenharmony_ci pa_hashmap_free(c->cards); 229753a5a1b3Sopenharmony_ci pa_hashmap_free(c->sinks_by_path); 229853a5a1b3Sopenharmony_ci pa_hashmap_free(c->sinks_by_index); 229953a5a1b3Sopenharmony_ci pa_hashmap_free(c->sources_by_path); 230053a5a1b3Sopenharmony_ci pa_hashmap_free(c->sources_by_index); 230153a5a1b3Sopenharmony_ci pa_hashmap_free(c->playback_streams); 230253a5a1b3Sopenharmony_ci pa_hashmap_free(c->record_streams); 230353a5a1b3Sopenharmony_ci pa_hashmap_free(c->samples); 230453a5a1b3Sopenharmony_ci pa_hashmap_free(c->modules); 230553a5a1b3Sopenharmony_ci pa_hashmap_free(c->clients); 230653a5a1b3Sopenharmony_ci pa_hook_slot_free(c->module_new_slot); 230753a5a1b3Sopenharmony_ci pa_hook_slot_free(c->module_removed_slot); 230853a5a1b3Sopenharmony_ci pa_hook_slot_free(c->default_sink_changed_slot); 230953a5a1b3Sopenharmony_ci pa_hook_slot_free(c->default_source_changed_slot); 231053a5a1b3Sopenharmony_ci pa_hook_slot_free(c->sample_cache_new_slot); 231153a5a1b3Sopenharmony_ci pa_hook_slot_free(c->sample_cache_removed_slot); 231253a5a1b3Sopenharmony_ci pa_hook_slot_free(c->card_put_slot); 231353a5a1b3Sopenharmony_ci pa_hook_slot_free(c->card_unlink_slot); 231453a5a1b3Sopenharmony_ci pa_hook_slot_free(c->sink_input_put_slot); 231553a5a1b3Sopenharmony_ci pa_hook_slot_free(c->sink_input_unlink_slot); 231653a5a1b3Sopenharmony_ci pa_hook_slot_free(c->source_output_put_slot); 231753a5a1b3Sopenharmony_ci pa_hook_slot_free(c->source_output_unlink_slot); 231853a5a1b3Sopenharmony_ci pa_hook_slot_free(c->client_put_slot); 231953a5a1b3Sopenharmony_ci pa_hook_slot_free(c->client_unlink_slot); 232053a5a1b3Sopenharmony_ci pa_hook_slot_free(c->sink_put_slot); 232153a5a1b3Sopenharmony_ci pa_hook_slot_free(c->sink_unlink_slot); 232253a5a1b3Sopenharmony_ci pa_hook_slot_free(c->source_put_slot); 232353a5a1b3Sopenharmony_ci pa_hook_slot_free(c->source_unlink_slot); 232453a5a1b3Sopenharmony_ci pa_hook_slot_free(c->extension_registered_slot); 232553a5a1b3Sopenharmony_ci pa_hook_slot_free(c->extension_unregistered_slot); 232653a5a1b3Sopenharmony_ci pa_dbusiface_memstats_free(c->memstats); 232753a5a1b3Sopenharmony_ci 232853a5a1b3Sopenharmony_ci if (c->fallback_sink) 232953a5a1b3Sopenharmony_ci pa_sink_unref(c->fallback_sink); 233053a5a1b3Sopenharmony_ci if (c->fallback_source) 233153a5a1b3Sopenharmony_ci pa_source_unref(c->fallback_source); 233253a5a1b3Sopenharmony_ci 233353a5a1b3Sopenharmony_ci pa_dbus_protocol_unref(c->dbus_protocol); 233453a5a1b3Sopenharmony_ci 233553a5a1b3Sopenharmony_ci pa_xfree(c); 233653a5a1b3Sopenharmony_ci} 233753a5a1b3Sopenharmony_ci 233853a5a1b3Sopenharmony_ciconst char *pa_dbusiface_core_get_card_path(pa_dbusiface_core *c, const pa_card *card) { 233953a5a1b3Sopenharmony_ci pa_assert(c); 234053a5a1b3Sopenharmony_ci pa_assert(card); 234153a5a1b3Sopenharmony_ci 234253a5a1b3Sopenharmony_ci return pa_dbusiface_card_get_path(pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(card->index))); 234353a5a1b3Sopenharmony_ci} 234453a5a1b3Sopenharmony_ci 234553a5a1b3Sopenharmony_ciconst char *pa_dbusiface_core_get_sink_path(pa_dbusiface_core *c, const pa_sink *sink) { 234653a5a1b3Sopenharmony_ci pa_assert(c); 234753a5a1b3Sopenharmony_ci pa_assert(sink); 234853a5a1b3Sopenharmony_ci 234953a5a1b3Sopenharmony_ci return pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(sink->index))); 235053a5a1b3Sopenharmony_ci} 235153a5a1b3Sopenharmony_ci 235253a5a1b3Sopenharmony_ciconst char *pa_dbusiface_core_get_source_path(pa_dbusiface_core *c, const pa_source *source) { 235353a5a1b3Sopenharmony_ci pa_assert(c); 235453a5a1b3Sopenharmony_ci pa_assert(source); 235553a5a1b3Sopenharmony_ci 235653a5a1b3Sopenharmony_ci return pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(source->index))); 235753a5a1b3Sopenharmony_ci} 235853a5a1b3Sopenharmony_ci 235953a5a1b3Sopenharmony_ciconst char *pa_dbusiface_core_get_playback_stream_path(pa_dbusiface_core *c, const pa_sink_input *sink_input) { 236053a5a1b3Sopenharmony_ci pa_assert(c); 236153a5a1b3Sopenharmony_ci pa_assert(sink_input); 236253a5a1b3Sopenharmony_ci 236353a5a1b3Sopenharmony_ci return pa_dbusiface_stream_get_path(pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(sink_input->index))); 236453a5a1b3Sopenharmony_ci} 236553a5a1b3Sopenharmony_ci 236653a5a1b3Sopenharmony_ciconst char *pa_dbusiface_core_get_record_stream_path(pa_dbusiface_core *c, const pa_source_output *source_output) { 236753a5a1b3Sopenharmony_ci pa_assert(c); 236853a5a1b3Sopenharmony_ci pa_assert(source_output); 236953a5a1b3Sopenharmony_ci 237053a5a1b3Sopenharmony_ci return pa_dbusiface_stream_get_path(pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(source_output->index))); 237153a5a1b3Sopenharmony_ci} 237253a5a1b3Sopenharmony_ci 237353a5a1b3Sopenharmony_ciconst char *pa_dbusiface_core_get_module_path(pa_dbusiface_core *c, const pa_module *module) { 237453a5a1b3Sopenharmony_ci pa_assert(c); 237553a5a1b3Sopenharmony_ci pa_assert(module); 237653a5a1b3Sopenharmony_ci 237753a5a1b3Sopenharmony_ci return pa_dbusiface_module_get_path(pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(module->index))); 237853a5a1b3Sopenharmony_ci} 237953a5a1b3Sopenharmony_ci 238053a5a1b3Sopenharmony_ciconst char *pa_dbusiface_core_get_client_path(pa_dbusiface_core *c, const pa_client *client) { 238153a5a1b3Sopenharmony_ci pa_assert(c); 238253a5a1b3Sopenharmony_ci pa_assert(client); 238353a5a1b3Sopenharmony_ci 238453a5a1b3Sopenharmony_ci return pa_dbusiface_client_get_path(pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(client->index))); 238553a5a1b3Sopenharmony_ci} 238653a5a1b3Sopenharmony_ci 238753a5a1b3Sopenharmony_cipa_sink *pa_dbusiface_core_get_sink(pa_dbusiface_core *c, const char *object_path) { 238853a5a1b3Sopenharmony_ci pa_dbusiface_device *device = NULL; 238953a5a1b3Sopenharmony_ci 239053a5a1b3Sopenharmony_ci pa_assert(c); 239153a5a1b3Sopenharmony_ci pa_assert(object_path); 239253a5a1b3Sopenharmony_ci 239353a5a1b3Sopenharmony_ci device = pa_hashmap_get(c->sinks_by_path, object_path); 239453a5a1b3Sopenharmony_ci 239553a5a1b3Sopenharmony_ci if (device) 239653a5a1b3Sopenharmony_ci return pa_dbusiface_device_get_sink(device); 239753a5a1b3Sopenharmony_ci else 239853a5a1b3Sopenharmony_ci return NULL; 239953a5a1b3Sopenharmony_ci} 240053a5a1b3Sopenharmony_ci 240153a5a1b3Sopenharmony_cipa_source *pa_dbusiface_core_get_source(pa_dbusiface_core *c, const char *object_path) { 240253a5a1b3Sopenharmony_ci pa_dbusiface_device *device = NULL; 240353a5a1b3Sopenharmony_ci 240453a5a1b3Sopenharmony_ci pa_assert(c); 240553a5a1b3Sopenharmony_ci pa_assert(object_path); 240653a5a1b3Sopenharmony_ci 240753a5a1b3Sopenharmony_ci device = pa_hashmap_get(c->sources_by_path, object_path); 240853a5a1b3Sopenharmony_ci 240953a5a1b3Sopenharmony_ci if (device) 241053a5a1b3Sopenharmony_ci return pa_dbusiface_device_get_source(device); 241153a5a1b3Sopenharmony_ci else 241253a5a1b3Sopenharmony_ci return NULL; 241353a5a1b3Sopenharmony_ci} 2414