{ "high-priority", pa_config_parse_bool, &c->high_priority, NULL },
{ "realtime-scheduling", pa_config_parse_bool, &c->realtime_scheduling, NULL },
{ "disallow-module-loading", pa_config_parse_bool, &c->disallow_module_loading, NULL },
+ { "allow-module-loading", pa_config_parse_not_bool, &c->disallow_module_loading, NULL },
{ "disallow-exit", pa_config_parse_bool, &c->disallow_exit, NULL },
+ { "allow-exit", pa_config_parse_not_bool, &c->disallow_exit, NULL },
{ "use-pid-file", pa_config_parse_bool, &c->use_pid_file, NULL },
{ "system-instance", pa_config_parse_bool, &c->system_instance, NULL },
+#ifdef HAVE_DBUS
+ { "local-server-type", parse_server_type, c, NULL },
+#endif
{ "no-cpu-limit", pa_config_parse_bool, &c->no_cpu_limit, NULL },
+ { "cpu-limit", pa_config_parse_not_bool, &c->no_cpu_limit, NULL },
{ "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL },
+ { "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL },
{ "flat-volumes", pa_config_parse_bool, &c->flat_volumes, NULL },
{ "lock-memory", pa_config_parse_bool, &c->lock_memory, NULL },
{ "exit-idle-time", pa_config_parse_int, &c->exit_idle_time, NULL },
pa_strbuf_printf(s, "nice-level = %i\n", c->nice_level);
pa_strbuf_printf(s, "realtime-scheduling = %s\n", pa_yes_no(c->realtime_scheduling));
pa_strbuf_printf(s, "realtime-priority = %i\n", c->realtime_priority);
- pa_strbuf_printf(s, "disallow-module-loading = %s\n", pa_yes_no(c->disallow_module_loading));
- pa_strbuf_printf(s, "disallow-exit = %s\n", pa_yes_no(c->disallow_exit));
+ pa_strbuf_printf(s, "allow-module-loading = %s\n", pa_yes_no(!c->disallow_module_loading));
+ pa_strbuf_printf(s, "allow-exit = %s\n", pa_yes_no(!c->disallow_exit));
pa_strbuf_printf(s, "use-pid-file = %s\n", pa_yes_no(c->use_pid_file));
pa_strbuf_printf(s, "system-instance = %s\n", pa_yes_no(c->system_instance));
- pa_strbuf_printf(s, "no-cpu-limit = %s\n", pa_yes_no(c->no_cpu_limit));
- pa_strbuf_printf(s, "disable-shm = %s\n", pa_yes_no(c->disable_shm));
+#ifdef HAVE_DBUS
+ pa_strbuf_printf(s, "local-server-type = %s\n", server_type_to_string[c->local_server_type]);
+#endif
+ pa_strbuf_printf(s, "cpu-limit = %s\n", pa_yes_no(!c->no_cpu_limit));
+ pa_strbuf_printf(s, "enable-shm = %s\n", pa_yes_no(!c->disable_shm));
pa_strbuf_printf(s, "flat-volumes = %s\n", pa_yes_no(c->flat_volumes));
pa_strbuf_printf(s, "lock-memory = %s\n", pa_yes_no(c->lock_memory));
pa_strbuf_printf(s, "exit-idle-time = %i\n", c->exit_idle_time);
pa_dbus_pending_free(i);
}
}
- while ((key = pa_proplist_iterate(proplist, state))) {
+
+void pa_dbus_send_error(DBusConnection *c, DBusMessage *in_reply_to, const char *name, const char *format, ...) {
+ va_list ap;
+ char *message;
+ DBusMessage *reply = NULL;
+
+ pa_assert(c);
+ pa_assert(in_reply_to);
+ pa_assert(name);
+ pa_assert(format);
+
+ va_start(ap, format);
+ message = pa_vsprintf_malloc(format, ap);
+ va_end(ap);
+ pa_assert_se((reply = dbus_message_new_error(in_reply_to, name, message)));
+ pa_assert_se(dbus_connection_send(c, reply, NULL));
+
+ dbus_message_unref(reply);
+
+ pa_xfree(message);
+}
+
+void pa_dbus_send_empty_reply(DBusConnection *c, DBusMessage *in_reply_to) {
+ DBusMessage *reply = NULL;
+
+ pa_assert(c);
+ pa_assert(in_reply_to);
+
+ pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+ pa_assert_se(dbus_connection_send(c, reply, NULL));
+ dbus_message_unref(reply);
+}
+
+void pa_dbus_send_basic_value_reply(DBusConnection *c, DBusMessage *in_reply_to, int type, void *data) {
+ DBusMessage *reply = NULL;
+
+ pa_assert(c);
+ pa_assert(in_reply_to);
+ pa_assert(dbus_type_is_basic(type));
+ pa_assert(data);
+
+ pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+ pa_assert_se(dbus_message_append_args(reply, type, data, DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_connection_send(c, reply, NULL));
+ dbus_message_unref(reply);
+}
+
+static const char *signature_from_basic_type(int type) {
+ switch (type) {
+ case DBUS_TYPE_BOOLEAN: return DBUS_TYPE_BOOLEAN_AS_STRING;
+ case DBUS_TYPE_BYTE: return DBUS_TYPE_BYTE_AS_STRING;
+ case DBUS_TYPE_INT16: return DBUS_TYPE_INT16_AS_STRING;
+ case DBUS_TYPE_UINT16: return DBUS_TYPE_UINT16_AS_STRING;
+ case DBUS_TYPE_INT32: return DBUS_TYPE_INT32_AS_STRING;
+ case DBUS_TYPE_UINT32: return DBUS_TYPE_UINT32_AS_STRING;
+ case DBUS_TYPE_INT64: return DBUS_TYPE_INT64_AS_STRING;
+ case DBUS_TYPE_UINT64: return DBUS_TYPE_UINT64_AS_STRING;
+ case DBUS_TYPE_DOUBLE: return DBUS_TYPE_DOUBLE_AS_STRING;
+ case DBUS_TYPE_STRING: return DBUS_TYPE_STRING_AS_STRING;
+ case DBUS_TYPE_OBJECT_PATH: return DBUS_TYPE_OBJECT_PATH_AS_STRING;
+ case DBUS_TYPE_SIGNATURE: return DBUS_TYPE_SIGNATURE_AS_STRING;
+ default: pa_assert_not_reached();
+ }
+}
+
+void pa_dbus_send_basic_variant_reply(DBusConnection *c, DBusMessage *in_reply_to, int type, void *data) {
+ DBusMessage *reply = NULL;
+ DBusMessageIter msg_iter;
+ DBusMessageIter variant_iter;
+
+ pa_assert(c);
+ pa_assert(in_reply_to);
+ pa_assert(dbus_type_is_basic(type));
+ pa_assert(data);
+
+ pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+ dbus_message_iter_init_append(reply, &msg_iter);
+ pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_VARIANT, signature_from_basic_type(type), &variant_iter));
+ pa_assert_se(dbus_message_iter_append_basic(&variant_iter, type, data));
+ pa_assert_se(dbus_message_iter_close_container(&msg_iter, &variant_iter));
+ pa_assert_se(dbus_connection_send(c, reply, NULL));
+ dbus_message_unref(reply);
+}
+
+/* Note: returns sizeof(char*) for strings, object paths and signatures. */
+static unsigned basic_type_size(int type) {
+ switch (type) {
+ case DBUS_TYPE_BOOLEAN: return sizeof(dbus_bool_t);
+ case DBUS_TYPE_BYTE: return 1;
+ case DBUS_TYPE_INT16: return sizeof(dbus_int16_t);
+ case DBUS_TYPE_UINT16: return sizeof(dbus_uint16_t);
+ case DBUS_TYPE_INT32: return sizeof(dbus_int32_t);
+ case DBUS_TYPE_UINT32: return sizeof(dbus_uint32_t);
+ case DBUS_TYPE_INT64: return sizeof(dbus_int64_t);
+ case DBUS_TYPE_UINT64: return sizeof(dbus_uint64_t);
+ case DBUS_TYPE_DOUBLE: return sizeof(double);
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_SIGNATURE: return sizeof(char*);
+ default: pa_assert_not_reached();
+ }
+}
+
+void pa_dbus_send_basic_array_variant_reply(DBusConnection *c, DBusMessage *in_reply_to, int item_type, void *array, unsigned n) {
+ DBusMessage *reply = NULL;
+ DBusMessageIter msg_iter;
+
+ pa_assert(c);
+ pa_assert(in_reply_to);
+ pa_assert(dbus_type_is_basic(item_type));
+ pa_assert(array || n == 0);
+
+ pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+ dbus_message_iter_init_append(reply, &msg_iter);
+ pa_dbus_append_basic_array_variant(&msg_iter, item_type, array, n);
+ pa_assert_se(dbus_connection_send(c, reply, NULL));
+ dbus_message_unref(reply);
+}
+
+void pa_dbus_send_proplist_variant_reply(DBusConnection *c, DBusMessage *in_reply_to, pa_proplist *proplist) {
+ DBusMessage *reply = NULL;
+ DBusMessageIter msg_iter;
+
+ pa_assert(c);
+ pa_assert(in_reply_to);
+ pa_assert(proplist);
+
+ pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+ dbus_message_iter_init_append(reply, &msg_iter);
+ pa_dbus_append_proplist_variant(&msg_iter, proplist);
+ pa_assert_se(dbus_connection_send(c, reply, NULL));
+ dbus_message_unref(reply);
+}
+
+void pa_dbus_append_basic_array(DBusMessageIter *iter, int item_type, const void *array, unsigned n) {
+ DBusMessageIter array_iter;
+ unsigned i;
+ unsigned item_size;
+
+ pa_assert(iter);
+ pa_assert(dbus_type_is_basic(item_type));
+ pa_assert(array || n == 0);
+
+ item_size = basic_type_size(item_type);
+
+ pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, signature_from_basic_type(item_type), &array_iter));
+
+ for (i = 0; i < n; ++i)
+ pa_assert_se(dbus_message_iter_append_basic(&array_iter, item_type, &((uint8_t*) array)[i * item_size]));
+
+ pa_assert_se(dbus_message_iter_close_container(iter, &array_iter));
+};
+
+void pa_dbus_append_basic_variant(DBusMessageIter *iter, int type, void *data) {
+ DBusMessageIter variant_iter;
+
+ pa_assert(iter);
+ pa_assert(dbus_type_is_basic(type));
+ pa_assert(data);
+
+ pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, signature_from_basic_type(type), &variant_iter));
+ pa_assert_se(dbus_message_iter_append_basic(&variant_iter, type, data));
+ pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
+}
+
+void pa_dbus_append_basic_array_variant(DBusMessageIter *iter, int item_type, const void *array, unsigned n) {
+ DBusMessageIter variant_iter;
+ char *array_signature;
+
+ pa_assert(iter);
+ pa_assert(dbus_type_is_basic(item_type));
+ pa_assert(array || n == 0);
+
+ array_signature = pa_sprintf_malloc("a%c", *signature_from_basic_type(item_type));
+
+ pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, array_signature, &variant_iter));
+ pa_dbus_append_basic_array(&variant_iter, item_type, array, n);
+ pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
+
+ pa_xfree(array_signature);
+}
+
+void pa_dbus_append_basic_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, int type, void *data) {
+ DBusMessageIter dict_entry_iter;
+
+ pa_assert(dict_iter);
+ pa_assert(key);
+ pa_assert(dbus_type_is_basic(type));
+ pa_assert(data);
+
+ pa_assert_se(dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+ pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+ pa_dbus_append_basic_variant(&dict_entry_iter, type, data);
+ pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
+}
+
+void pa_dbus_append_basic_array_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, int item_type, const void *array, unsigned n) {
+ DBusMessageIter dict_entry_iter;
+
+ pa_assert(dict_iter);
+ pa_assert(key);
+ pa_assert(dbus_type_is_basic(item_type));
+ pa_assert(array || n == 0);
+
+ pa_assert_se(dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+ pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+ pa_dbus_append_basic_array_variant(&dict_entry_iter, item_type, array, n);
+ pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
+}
+
+void pa_dbus_append_proplist(DBusMessageIter *iter, pa_proplist *proplist) {
+ DBusMessageIter dict_iter;
+ DBusMessageIter dict_entry_iter;
+ DBusMessageIter array_iter;
+ void *state = NULL;
+ const char *key;
+
+ pa_assert(iter);
+ pa_assert(proplist);
+
+ pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{say}", &dict_iter));
+
++ while ((key = pa_proplist_iterate(proplist, &state))) {
+ const void *value = NULL;
+ size_t nbytes;
+
+ pa_assert_se(pa_proplist_get(proplist, key, &value, &nbytes) >= 0);
+
+ pa_assert_se(dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+
+ pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+
+ pa_assert_se(dbus_message_iter_open_container(&dict_entry_iter, DBUS_TYPE_ARRAY, "y", &array_iter));
+ pa_assert_se(dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE, &value, nbytes));
+ pa_assert_se(dbus_message_iter_close_container(&dict_entry_iter, &array_iter));
+
+ pa_assert_se(dbus_message_iter_close_container(&dict_iter, &dict_entry_iter));
+ }
+
+ pa_assert_se(dbus_message_iter_close_container(iter, &dict_iter));
+}
+
+void pa_dbus_append_proplist_variant(DBusMessageIter *iter, pa_proplist *proplist) {
+ DBusMessageIter variant_iter;
+
+ pa_assert(iter);
+ pa_assert(proplist);
+
+ pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{say}", &variant_iter));
+ pa_dbus_append_proplist(&variant_iter, proplist);
+ pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
+}
+
+void pa_dbus_append_proplist_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, pa_proplist *proplist) {
+ DBusMessageIter dict_entry_iter;
+
+ pa_assert(dict_iter);
+ pa_assert(key);
+ pa_assert(proplist);
+
+ pa_assert_se(dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+ pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+ pa_dbus_append_proplist_variant(&dict_entry_iter, proplist);
+ pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
+}
+
+int pa_dbus_get_basic_set_property_arg(DBusConnection *c, DBusMessage *msg, int type, void *data) {
+ DBusMessageIter msg_iter;
+ DBusMessageIter variant_iter;
+
+ pa_assert(c);
+ pa_assert(msg);
+ pa_assert(dbus_type_is_basic(type));
+ pa_assert(data);
+
+ /* Skip the interface and property name arguments. */
+ if (!dbus_message_iter_init(msg, &msg_iter) || !dbus_message_iter_next(&msg_iter) || !dbus_message_iter_next(&msg_iter)) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments.");
+ return -1;
+ }
+
+ if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_VARIANT) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Message argument isn't a variant.");
+ return -1;
+ }
+
+ dbus_message_iter_recurse(&msg_iter, &variant_iter);
+
+ if (pa_dbus_get_basic_arg(c, msg, &variant_iter, type, data) < 0)
+ return -1;
+
+ return 0;
+}
+
+int pa_dbus_get_fixed_array_set_property_arg(DBusConnection *c, DBusMessage *msg, int item_type, void *data, unsigned *n) {
+ DBusMessageIter msg_iter;
+ DBusMessageIter variant_iter;
+
+ pa_assert(c);
+ pa_assert(msg);
+ pa_assert(dbus_type_is_fixed(item_type));
+ pa_assert(data);
+ pa_assert(n);
+
+ /* Skip the interface and property name arguments. */
+ if (!dbus_message_iter_init(msg, &msg_iter) || !dbus_message_iter_next(&msg_iter) || !dbus_message_iter_next(&msg_iter)) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments.");
+ return -1;
+ }
+
+ if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_VARIANT) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Message argument isn't a variant.");
+ return -1;
+ }
+
+ dbus_message_iter_recurse(&msg_iter, &variant_iter);
+
+ if (pa_dbus_get_fixed_array_arg(c, msg, &variant_iter, item_type, data, n) < 0)
+ return -1;
+
+ return 0;
+}
+
+int pa_dbus_get_basic_arg(DBusConnection *c, DBusMessage *msg, DBusMessageIter *iter, int type, void *data) {
+ int arg_type;
+
+ pa_assert(c);
+ pa_assert(msg);
+ pa_assert(iter);
+ pa_assert(dbus_type_is_basic(type));
+ pa_assert(data);
+
+ arg_type = dbus_message_iter_get_arg_type(iter);
+ if (arg_type != type) {
+ if (arg_type == DBUS_TYPE_INVALID)
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments. D-Bus type '%c' expected.", (char) type);
+ else
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Wrong argument type: '%c'. Expected type '%c'.", (char) arg_type, (char) type);
+ return -1;
+ }
+
+ dbus_message_iter_get_basic(iter, data);
+
+ dbus_message_iter_next(iter);
+
+ return 0;
+}
+
+int pa_dbus_get_fixed_array_arg(DBusConnection *c, DBusMessage *msg, DBusMessageIter *iter, int item_type, void *array, unsigned *n) {
+ DBusMessageIter array_iter;
+ int signed_n;
+ int arg_type;
+ int element_type;
+
+ pa_assert(c);
+ pa_assert(msg);
+ pa_assert(iter);
+ pa_assert(dbus_type_is_fixed(item_type));
+ pa_assert(array);
+ pa_assert(n);
+
+ arg_type = dbus_message_iter_get_arg_type(iter);
+ if (arg_type != DBUS_TYPE_ARRAY) {
+ if (arg_type == DBUS_TYPE_INVALID)
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments. An array of type '%c' was expected.", (char) item_type);
+ else
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Wrong argument type: '%c'. An array of type '%c' was expected.", (char) arg_type, (char) item_type);
+ return -1;
+ }
+
+ element_type = dbus_message_iter_get_element_type(iter);
+ if (element_type != item_type) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Wrong array element type: '%c'. Element type '%c' was expected.", (char) element_type, (char) item_type);
+ return -1;
+ }
+
+ dbus_message_iter_recurse(iter, &array_iter);
+
+ dbus_message_iter_get_fixed_array(&array_iter, array, &signed_n);
+
+ dbus_message_iter_next(iter);
+
+ pa_assert(signed_n >= 0);
+
+ *n = signed_n;
+
+ return 0;
+}
+
+pa_proplist *pa_dbus_get_proplist_arg(DBusConnection *c, DBusMessage *msg, DBusMessageIter *iter) {
+ DBusMessageIter dict_iter;
+ DBusMessageIter dict_entry_iter;
+ int arg_type;
+ pa_proplist *proplist = NULL;
+ const char *key;
+ const uint8_t *value;
+ int value_length;
+
+ pa_assert(c);
+ pa_assert(msg);
+ pa_assert(iter);
+
+ arg_type = dbus_message_iter_get_arg_type(iter);
+ if (arg_type != DBUS_TYPE_ARRAY) {
+ if (arg_type == DBUS_TYPE_INVALID)
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments. An array was expected.");
+ else
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Wrong argument type: '%c'. An array was expected.", (char) arg_type);
+ return NULL;
+ }
+
+ arg_type = dbus_message_iter_get_element_type(iter);
+ if (arg_type != DBUS_TYPE_DICT_ENTRY) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Wrong array element type: '%c'. A dictionary entry was expected.", (char) arg_type);
+ return NULL;
+ }
+
+ proplist = pa_proplist_new();
+
+ dbus_message_iter_recurse(iter, &dict_iter);
+
+ while (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_INVALID) {
+ dbus_message_iter_recurse(&dict_iter, &dict_entry_iter);
+
+ arg_type = dbus_message_iter_get_arg_type(&dict_entry_iter);
+ if (arg_type != DBUS_TYPE_STRING) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict key type: '%c'. A string was expected.", (char) arg_type);
+ goto fail;
+ }
+
+ dbus_message_iter_get_basic(&dict_entry_iter, &key);
+ dbus_message_iter_next(&dict_entry_iter);
+
+ if (strlen(key) <= 0 || !pa_ascii_valid(key)) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Invalid property list key.");
+ goto fail;
+ }
+
+ arg_type = dbus_message_iter_get_arg_type(&dict_entry_iter);
+ if (arg_type != DBUS_TYPE_ARRAY) {
+ if (arg_type == DBUS_TYPE_INVALID)
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Dict value missing.");
+ else
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict value type: '%c'. An array was expected.", (char) arg_type);
+ goto fail;
+ }
+
+ arg_type = dbus_message_iter_get_element_type(&dict_entry_iter);
+ if (arg_type != DBUS_TYPE_BYTE) {
+ pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict value item type: '%c'. A byte was expected.", (char) arg_type);
+ goto fail;
+ }
+
+ dbus_message_iter_get_fixed_array(&dict_entry_iter, &value, &value_length);
+
+ pa_assert(value_length >= 0);
+
+ pa_assert_se(pa_proplist_set(proplist, key, value, value_length) >= 0);
+
+ dbus_message_iter_next(&dict_iter);
+ }
+
+ dbus_message_iter_next(iter);
+
+ return proplist;
+
+fail:
+ if (proplist)
+ pa_proplist_free(proplist);
+
+ return NULL;
+}
pa_assert_se(e = pa_hashmap_remove(c->namereg, name));
- if (c->default_sink == e->data)
- pa_namereg_set_default_sink(c, NULL);
- else if (c->default_source == e->data)
- pa_namereg_set_default_source(c, NULL);
+ if (c->default_sink == e->data) {
- pa_sink *new_default = pa_idxset_first(c->sinks, &idx);
++ pa_sink *new_default = NULL;
+
- if (new_default == e->data)
- new_default = pa_idxset_next(c->sinks, &idx);
++ /* FIXME: the selection here should be based priority values on
++ * the sinks */
++
++ PA_IDXSET_FOREACH(new_default, c->sinks, idx) {
++ if (new_default != e->data && PA_SINK_IS_LINKED(pa_sink_get_state(new_default)))
++ break;
++ }
+
+ pa_namereg_set_default_sink(c, new_default);
+
+ } else if (c->default_source == e->data) {
- pa_source *new_default;
++ pa_source *new_default = NULL;
+
- for (new_default = pa_idxset_first(c->sources, &idx); new_default; new_default = pa_idxset_next(c->sources, &idx)) {
- if (new_default != e->data && !new_default->monitor_of)
++ /* First, try to find one that isn't a monitor */
++ PA_IDXSET_FOREACH(new_default, c->sources, idx) {
++ if (new_default != e->data && !new_default->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(new_default)))
+ break;
+ }
+
+ if (!new_default) {
- new_default = pa_idxset_first(c->sources, &idx);
-
- if (new_default == e->data)
- new_default = pa_idxset_next(c->sources, &idx);
++ /* Then, fallback to a monitor */
++ PA_IDXSET_FOREACH(new_default, c->sources, idx) {
++ if (new_default != e->data && PA_SOURCE_IS_LINKED(pa_source_get_state(new_default)))
++ break;
++ }
+ }
+
+ pa_namereg_set_default_source(c, new_default);
+ }
pa_xfree(e->name);
pa_xfree(e);
return s;
}
+/* XXX: After removing old functionality, has this function become useless? */
pa_sink *pa_namereg_get_default_sink(pa_core *c) {
+ pa_sink *s;
+ uint32_t idx;
+
pa_assert(c);
- return c->default_sink;
- if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)))
++ if (!c->default_sink || PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)))
+ return c->default_sink;
+
++ /* The old default sink has become unlinked, set a new one. */
++
+ /* FIXME: the selection here should be based priority values on
+ * the sinks */
+
+ PA_IDXSET_FOREACH(s, c->sinks, idx)
+ if (PA_SINK_IS_LINKED(pa_sink_get_state(s)))
+ return pa_namereg_set_default_sink(c, s);
+
- return NULL;
++ return pa_namereg_set_default_sink(c, NULL);
}
+/* XXX: After removing old functionality, has this function become useless? */
pa_source *pa_namereg_get_default_source(pa_core *c) {
+ pa_source *s;
+ uint32_t idx;
+
pa_assert(c);
- return c->default_source;
- if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source)))
++ if (!c->default_source || PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source)))
+ return c->default_source;
+
++ /* The old default source has become unlinked, set a new one. */
++
+ /* First, try to find one that isn't a monitor */
+ PA_IDXSET_FOREACH(s, c->sources, idx)
+ if (!s->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+ return pa_namereg_set_default_source(c, s);
+
+ /* Then, fallback to a monitor */
+ PA_IDXSET_FOREACH(s, c->sources, idx)
+ if (PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
+ return pa_namereg_set_default_source(c, s);
+
- return NULL;
++ return pa_namereg_set_default_source(c, NULL);
}