char* context_info_str(pa_context* c) { return g_strdup_printf( "Server String: %s\n" "Library Protocol Version: %u\n" "Server Protocol Version: %u\n" "Is Local: %s\n" "Client Index: %u\n" "Tile Size: %zu", pa_context_get_server(c), pa_context_get_protocol_version(c), pa_context_get_server_protocol_version(c), pa_context_is_local(c) ? "yes" : "no", pa_context_get_index(c), pa_context_get_tile_size(c, NULL)); }
/** * Initializes the PulseAudio main loop and connects to the PulseAudio server. * @return a PulseAudio context on success, or NULL on error */ pa_context *vlc_pa_connect (vlc_object_t *obj, pa_threaded_mainloop **mlp) { msg_Dbg (obj, "using library version %s", pa_get_library_version ()); msg_Dbg (obj, " (compiled with version %s, protocol %u)", pa_get_headers_version (), PA_PROTOCOL_VERSION); /* Initialize main loop */ pa_threaded_mainloop *mainloop = pa_threaded_mainloop_new (); if (unlikely(mainloop == NULL)) return NULL; if (pa_threaded_mainloop_start (mainloop) < 0) { pa_threaded_mainloop_free (mainloop); return NULL; } /* Fill in context (client) properties */ char *ua = var_InheritString (obj, "user-agent"); pa_proplist *props = pa_proplist_new (); if (likely(props != NULL)) { pa_proplist_sets (props, PA_PROP_APPLICATION_NAME, ua); pa_proplist_sets (props, PA_PROP_APPLICATION_ID, "org.VideoLAN.VLC"); pa_proplist_sets (props, PA_PROP_APPLICATION_VERSION, PACKAGE_VERSION); pa_proplist_sets (props, PA_PROP_APPLICATION_ICON_NAME, PACKAGE_NAME); //pa_proplist_sets (props, PA_PROP_APPLICATION_LANGUAGE, _("C")); pa_proplist_sets (props, PA_PROP_APPLICATION_LANGUAGE, setlocale (LC_MESSAGES, NULL)); pa_proplist_setf (props, PA_PROP_APPLICATION_PROCESS_ID, "%lu", (unsigned long) getpid ()); //pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_BINARY, // PACKAGE_NAME); for (size_t max = sysconf (_SC_GETPW_R_SIZE_MAX), len = max % 1024 + 1024; len < max; len += 1024) { struct passwd pwbuf, *pw; char buf[len]; if (getpwuid_r (getuid (), &pwbuf, buf, sizeof (buf), &pw) == 0 && pw != NULL) pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_USER, pw->pw_name); } for (size_t max = sysconf (_SC_HOST_NAME_MAX), len = max % 1024 + 1024; len < max; len += 1024) { char hostname[len]; if (gethostname (hostname, sizeof (hostname)) == 0) pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_HOST, hostname); } const char *session = getenv ("XDG_SESSION_COOKIE"); if (session != NULL) { pa_proplist_setf (props, PA_PROP_APPLICATION_PROCESS_MACHINE_ID, "%.32s", session); /* XXX: is this valid? */ pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_SESSION_ID, session); } } /* Connect to PulseAudio daemon */ pa_context *ctx; pa_mainloop_api *api; pa_threaded_mainloop_lock (mainloop); api = pa_threaded_mainloop_get_api (mainloop); ctx = pa_context_new_with_proplist (api, ua, props); free (ua); if (props != NULL) pa_proplist_free (props); if (unlikely(ctx == NULL)) goto fail; pa_context_set_state_callback (ctx, context_state_cb, mainloop); if (pa_context_connect (ctx, NULL, 0, NULL) < 0 || context_wait (ctx, mainloop)) { vlc_pa_error (obj, "PulseAudio server connection failure", ctx); pa_context_unref (ctx); goto fail; } msg_Dbg (obj, "connected %s to %s as client #%"PRIu32, pa_context_is_local (ctx) ? "locally" : "remotely", pa_context_get_server (ctx), pa_context_get_index (ctx)); msg_Dbg (obj, "using protocol %"PRIu32", server protocol %"PRIu32, pa_context_get_protocol_version (ctx), pa_context_get_server_protocol_version (ctx)); pa_threaded_mainloop_unlock (mainloop); *mlp = mainloop; return ctx; fail: pa_threaded_mainloop_unlock (mainloop); pa_threaded_mainloop_stop (mainloop); pa_threaded_mainloop_free (mainloop); return NULL; }
static int pa_init_boilerplate(struct ao *ao) { struct priv *priv = ao->priv; char *host = priv->cfg_host && priv->cfg_host[0] ? priv->cfg_host : NULL; bool locked = false; pthread_mutex_init(&priv->wakeup_lock, NULL); pthread_cond_init(&priv->wakeup, NULL); if (!(priv->mainloop = pa_threaded_mainloop_new())) { MP_ERR(ao, "Failed to allocate main loop\n"); goto fail; } if (pa_threaded_mainloop_start(priv->mainloop) < 0) goto fail; pa_threaded_mainloop_lock(priv->mainloop); locked = true; if (!(priv->context = pa_context_new(pa_threaded_mainloop_get_api( priv->mainloop), ao->client_name))) { MP_ERR(ao, "Failed to allocate context\n"); goto fail; } MP_VERBOSE(ao, "Library version: %s\n", pa_get_library_version()); MP_VERBOSE(ao, "Proto: %lu\n", (long)pa_context_get_protocol_version(priv->context)); MP_VERBOSE(ao, "Server proto: %lu\n", (long)pa_context_get_server_protocol_version(priv->context)); pa_context_set_state_callback(priv->context, context_state_cb, ao); pa_context_set_subscribe_callback(priv->context, subscribe_cb, ao); if (pa_context_connect(priv->context, host, 0, NULL) < 0) goto fail; /* Wait until the context is ready */ while (1) { int state = pa_context_get_state(priv->context); if (state == PA_CONTEXT_READY) break; if (!PA_CONTEXT_IS_GOOD(state)) goto fail; pa_threaded_mainloop_wait(priv->mainloop); } pa_threaded_mainloop_unlock(priv->mainloop); return 0; fail: if (locked) pa_threaded_mainloop_unlock(priv->mainloop); if (priv->context) { pa_threaded_mainloop_lock(priv->mainloop); if (!(pa_context_errno(priv->context) == PA_ERR_CONNECTIONREFUSED && ao->probing)) GENERIC_ERR_MSG("Init failed"); pa_threaded_mainloop_unlock(priv->mainloop); } uninit(ao); return -1; }