+bool description_pulseaudio(uint32_t sink_idx, const char *sink_name, char buffer[MAX_SINK_DESCRIPTION_LEN]) {
+ if (!context_ready || default_sink_idx == DEFAULT_SINK_INDEX) {
+ return false;
+ }
+
+ pthread_mutex_lock(&pulse_mutex);
+ const index_info_t *entry;
+ TAILQ_FOREACH(entry, &cached_info, entries) {
+ if (sink_name) {
+ if (!entry->name || strcmp(entry->name, sink_name)) {
+ continue;
+ }
+ } else {
+ if (entry->idx != sink_idx) {
+ continue;
+ }
+ }
+ strncpy(buffer, entry->description, sizeof(entry->description) - 1);
+ pthread_mutex_unlock(&pulse_mutex);
+ buffer[sizeof(entry->description) - 1] = '\0';
+ return true;
+ }
+ pthread_mutex_unlock(&pulse_mutex);
+ /* first time requires a prime callback call because we only get updates
+ * when the description or volume actually changes, but we need it to be
+ * correct even if it never changes */
+ pa_threaded_mainloop_lock(main_loop);
+ get_sink_info(context, sink_idx, sink_name);
+ pa_threaded_mainloop_unlock(main_loop);
+ /* show empty string while we don't have this information */
+ buffer[0] = '\0';
+ return true;
+}
+