]> code.delx.au - pulseaudio/commitdiff
Merge branch 'master' of git://0pointer.de/pulseaudio into dbus-work
authorTanu Kaskinen <tanuk@iki.fi>
Sun, 16 Aug 2009 18:25:48 +0000 (21:25 +0300)
committerTanu Kaskinen <tanuk@iki.fi>
Sun, 16 Aug 2009 18:25:48 +0000 (21:25 +0300)
Conflicts:
src/Makefile.am
src/daemon/daemon-conf.c
src/daemon/daemon.conf.in
src/modules/module-stream-restore.c
src/pulse/client-conf.c
src/pulsecore/namereg.c

15 files changed:
1  2 
configure.ac
po/es.po
po/pt_BR.po
src/Makefile.am
src/daemon/daemon-conf.c
src/daemon/daemon.conf.in
src/daemon/main.c
src/map-file
src/modules/module-stream-restore.c
src/pulse/client-conf.c
src/pulse/client.conf.in
src/pulsecore/core-util.c
src/pulsecore/core-util.h
src/pulsecore/dbus-util.c
src/pulsecore/namereg.c

diff --cc configure.ac
Simple merge
diff --cc po/es.po
index 8af1c7384915802352a39dae37dddd8e4708bdf2,b36d693949d6635cba5112fe94e818a826250210..6995716ef7ee3415cba422513d85afeb993139ee
+++ b/po/es.po
@@@ -2600,9 -2408,8 +2408,7 @@@ msgstr "Servidor de Sonido PulseAudio
  #~ "Tipo: %s\n"
  #~ "Módulo: %s\n"
  #~ "Argumento: %s\n"
  #~ msgid "sink"
  #~ msgstr "destino"
  #~ msgid "source"
  #~ msgstr "fuente"
 -
diff --cc po/pt_BR.po
index fd4f539193275ff2b7fefdc8c0d65ecdc6e419ac,20365eebad2cf750e0ff52c868aa2762af32a162..323e5b944d10392696a38c6f8be6882c155eeabd
@@@ -2497,6 -2370,6 +2370,5 @@@ msgstr "Servidor de som PulseAudio
  #~ msgstr ""
  #~ "', ou eleve o RLIMIT_NICE/RLIMIT_RTPRIO dos limites do recurso para este "
  #~ "usuário."
  #~ msgid "socketpair(): %s"
  #~ msgstr "socketpair(): %s"
 -
diff --cc src/Makefile.am
Simple merge
index ace460edc05b6357dd580a0d6ab25c3884a5ead2,9a87b5552846ed1ca62375643bc76ee45cef83ee..31f29009417bebd430c1ceaa47fbdf3fa688c91a
@@@ -476,14 -441,15 +476,18 @@@ int pa_daemon_conf_load(pa_daemon_conf 
          { "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 },
@@@ -669,15 -629,12 +675,15 @@@ char *pa_daemon_conf_dump(pa_daemon_con
      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);
index 9bea6148c4da945d01555477c80a9d67b68b1467,d8b58d8a0a40d729fa24ee388e82f79594322c60..a11fd06c56536243b26b2188dea471f0da25f15b
  
  ; daemonize = no
  ; fail = yes
- ; disallow-module-loading = no
- ; disallow-exit = no
+ ; allow-module-loading = yes
+ ; allow-exit = yes
  ; use-pid-file = yes
  ; system-instance = no
- ; disable-shm = no
 +; local-server-type = user
+ ; enable-shm = yes
  ; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
  ; lock-memory = no
- ; no-cpu-limit = no
+ ; cpu-limit = yes
  
  ; high-priority = yes
  ; nice-level = -11
Simple merge
diff --cc src/map-file
Simple merge
index e90630310792f4bf678028bee5960c3f34ce772a,e560bd2805594137e1ec0724c7e3996f7faf24d7..076b39189ca95509d2e1bde1a2cff3c0cc6349ae
@@@ -106,15 -100,9 +106,15 @@@ struct userdata 
  
      pa_native_protocol *protocol;
      pa_idxset *subscribed;
 +
 +#ifdef HAVE_DBUS
 +    pa_dbus_protocol *dbus_protocol;
 +    pa_hashmap *dbus_entries;
 +    uint32_t next_index; /* For generating object paths for entries. */
 +#endif
  };
  
- #define ENTRY_VERSION 2
+ #define ENTRY_VERSION 3
  
  struct entry {
      uint8_t version;
@@@ -1216,7 -324,10 +1231,11 @@@ static void subscribe_callback(pa_core 
              pa_strlcpy(entry.device, sink_input->sink->name, sizeof(entry.device));
              entry.device_valid = TRUE;
  
 +            device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry.device, old->device));
+             if (sink_input->sink->card) {
+                 pa_strlcpy(entry.card, sink_input->sink->card->name, sizeof(entry.card));
+                 entry.card_valid = TRUE;
+             }
          }
  
      } else {
              pa_strlcpy(entry.device, source_output->source->name, sizeof(entry.device));
              entry.device_valid = source_output->save_source;
  
 +            device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry.device, old->device));
++
+             if (source_output->source->card) {
+                 pa_strlcpy(entry.card, source_output->source->card->name, sizeof(entry.card));
+                 entry.card_valid = TRUE;
+             }
          }
      }
  
index 8eab1094d817135905dee9c434e78b88987588a9,4aa4ba1fc82cf5e66378129cc6df9942f8c4e3db..62c06f6aa7f8530a6a491c67d4b6c7b67b12a3bf
@@@ -94,17 -92,17 +94,18 @@@ int pa_client_conf_load(pa_client_conf 
  
      /* Prepare the configuration parse table */
      pa_config_item table[] = {
-         { "daemon-binary",          pa_config_parse_string,  &c->daemon_binary, NULL },
-         { "extra-arguments",        pa_config_parse_string,  &c->extra_arguments, NULL },
-         { "default-sink",           pa_config_parse_string,  &c->default_sink, NULL },
-         { "default-source",         pa_config_parse_string,  &c->default_source, NULL },
-         { "default-server",         pa_config_parse_string,  &c->default_server, NULL },
-         { "default-dbus-server",    pa_config_parse_string,  &c->default_dbus_server, NULL },
-         { "autospawn",              pa_config_parse_bool,    &c->autospawn, NULL },
-         { "cookie-file",            pa_config_parse_string,  &c->cookie_file, NULL },
-         { "disable-shm",            pa_config_parse_bool,    &c->disable_shm, NULL },
-         { "shm-size-bytes",         pa_config_parse_size,    &c->shm_size, NULL },
-         { NULL,                     NULL,                    NULL, NULL },
+         { "daemon-binary",          pa_config_parse_string,   &c->daemon_binary, NULL },
+         { "extra-arguments",        pa_config_parse_string,   &c->extra_arguments, NULL },
+         { "default-sink",           pa_config_parse_string,   &c->default_sink, NULL },
+         { "default-source",         pa_config_parse_string,   &c->default_source, NULL },
+         { "default-server",         pa_config_parse_string,   &c->default_server, NULL },
++        { "default-dbus-server",    pa_config_parse_string,   &c->default_dbus_server, NULL },
+         { "autospawn",              pa_config_parse_bool,     &c->autospawn, NULL },
+         { "cookie-file",            pa_config_parse_string,   &c->cookie_file, NULL },
+         { "disable-shm",            pa_config_parse_bool,     &c->disable_shm, NULL },
+         { "enable-shm",             pa_config_parse_not_bool, &c->disable_shm, NULL },
+         { "shm-size-bytes",         pa_config_parse_size,     &c->shm_size, NULL },
+         { NULL,                     NULL,                     NULL, NULL },
      };
  
      if (filename) {
Simple merge
Simple merge
Simple merge
index 903acadb7447b89b6c6590df4e110cd70eb690db,4e6148f0770e43a84ea3a0e05e04038164e78fe1..b45e6a6c6d0e99b4a970b62502439a4f78cee2e8
@@@ -445,475 -422,3 +445,475 @@@ void pa_dbus_free_pending_list(pa_dbus_
          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;
 +}
index 046c87b200487b07690c8872bebfeed0066e194b,e26923d41617b4eaacb189f89ed89bfba33012fc..d7d83c5e8db233b2ecb579525f6158aeeece8a6d
@@@ -166,31 -160,10 +166,38 @@@ void pa_namereg_unregister(pa_core *c, 
  
      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);
@@@ -268,16 -248,43 +281,49 @@@ pa_source* pa_namereg_set_default_sourc
      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);
  }