From 065e7644acf6cdbda0611b69ef06f97cda960110 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 3 Aug 2008 16:44:38 +0200 Subject: make all protocol objects global singletons --- src/modules/module-native-protocol-fd.c | 24 +- src/modules/module-protocol-stub.c | 403 ++++++++++++++++++++------------ src/modules/module-tunnel.c | 44 +--- src/modules/module-x11-publish.c | 101 ++++---- 4 files changed, 329 insertions(+), 243 deletions(-) (limited to 'src/modules') diff --git a/src/modules/module-native-protocol-fd.c b/src/modules/module-native-protocol-fd.c index 1a6f5368..fa9c0e4f 100644 --- a/src/modules/module-native-protocol-fd.c +++ b/src/modules/module-native-protocol-fd.c @@ -42,8 +42,6 @@ PA_MODULE_LOAD_ONCE(TRUE); static const char* const valid_modargs[] = { "fd", - "public", - "cookie", NULL, }; @@ -51,6 +49,7 @@ int pa__init(pa_module*m) { pa_iochannel *io; pa_modargs *ma; int fd, r = -1; + pa_native_options *options = NULL; pa_assert(m); @@ -64,12 +63,17 @@ int pa__init(pa_module*m) { goto finish; } + options = pa_native_options_new(); + options->module = m; + options->auth_anonymous = TRUE; + io = pa_iochannel_new(m->core->mainloop, fd, fd); - if (!(m->userdata = pa_protocol_native_new_iochannel(m->core, io, m, ma))) { - pa_iochannel_free(io); - goto finish; - } + m->userdata = pa_native_protocol_get(m->core); + + pa_native_protocol_connect(m->userdata, io, options); + + pa_native_options_unref(options); r = 0; @@ -77,11 +81,17 @@ finish: if (ma) pa_modargs_free(ma); + if (options) + pa_native_options_unref(options); + return r; } void pa__done(pa_module*m) { pa_assert(m); - pa_protocol_native_free(m->userdata); + if (m->userdata) { + pa_native_protocol_disconnect(m->userdata, m); + pa_native_protocol_unref(m->userdata); + } } diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c index 0c9529c3..8136c6fc 100644 --- a/src/modules/module-protocol-stub.c +++ b/src/modules/module-protocol-stub.c @@ -62,19 +62,19 @@ #endif #if defined(USE_PROTOCOL_SIMPLE) - #include - #define protocol_new pa_protocol_simple_new - #define protocol_free pa_protocol_simple_free - #define TCPWRAP_SERVICE "pulseaudio-simple" - #define IPV4_PORT 4711 - #define UNIX_SOCKET "simple" - #define MODULE_ARGUMENTS "rate", "format", "channels", "sink", "source", "playback", "record", - #if defined(USE_TCP_SOCKETS) - #include "module-simple-protocol-tcp-symdef.h" - #else - #include "module-simple-protocol-unix-symdef.h" - #endif -PA_MODULE_DESCRIPTION("Simple protocol "SOCKET_DESCRIPTION); +# include +# define TCPWRAP_SERVICE "pulseaudio-simple" +# define IPV4_PORT 4711 +# define UNIX_SOCKET "simple" +# define MODULE_ARGUMENTS "rate", "format", "channels", "sink", "source", "playback", "record", + +# if defined(USE_TCP_SOCKETS) +# include "module-simple-protocol-tcp-symdef.h" +# else +# include "module-simple-protocol-unix-symdef.h" +# endif + + PA_MODULE_DESCRIPTION("Simple protocol "SOCKET_DESCRIPTION); PA_MODULE_USAGE("rate= " "format= " "channels= " @@ -84,96 +84,96 @@ PA_MODULE_DESCRIPTION("Simple protocol "SOCKET_DESCRIPTION); "record= " SOCKET_USAGE); #elif defined(USE_PROTOCOL_CLI) - #include - #define protocol_new pa_protocol_cli_new - #define protocol_free pa_protocol_cli_free - #define TCPWRAP_SERVICE "pulseaudio-cli" - #define IPV4_PORT 4712 - #define UNIX_SOCKET "cli" - #define MODULE_ARGUMENTS - #ifdef USE_TCP_SOCKETS - #include "module-cli-protocol-tcp-symdef.h" - #else - #include "module-cli-protocol-unix-symdef.h" - #endif +# include +# define TCPWRAP_SERVICE "pulseaudio-cli" +# define IPV4_PORT 4712 +# define UNIX_SOCKET "cli" +# define MODULE_ARGUMENTS + +# ifdef USE_TCP_SOCKETS +# include "module-cli-protocol-tcp-symdef.h" +# else +# include "module-cli-protocol-unix-symdef.h" +# endif + PA_MODULE_DESCRIPTION("Command line interface protocol "SOCKET_DESCRIPTION); PA_MODULE_USAGE(SOCKET_USAGE); #elif defined(USE_PROTOCOL_HTTP) - #include - #define protocol_new pa_protocol_http_new - #define protocol_free pa_protocol_http_free - #define TCPWRAP_SERVICE "pulseaudio-http" - #define IPV4_PORT 4714 - #define UNIX_SOCKET "http" - #define MODULE_ARGUMENTS - #ifdef USE_TCP_SOCKETS - #include "module-http-protocol-tcp-symdef.h" - #else - #include "module-http-protocol-unix-symdef.h" - #endif +# include +# define TCPWRAP_SERVICE "pulseaudio-http" +# define IPV4_PORT 4714 +# define UNIX_SOCKET "http" +# define MODULE_ARGUMENTS + +# ifdef USE_TCP_SOCKETS +# include "module-http-protocol-tcp-symdef.h" +# else +# include "module-http-protocol-unix-symdef.h" +# endif + PA_MODULE_DESCRIPTION("HTTP "SOCKET_DESCRIPTION); PA_MODULE_USAGE(SOCKET_USAGE); #elif defined(USE_PROTOCOL_NATIVE) - #include - #define protocol_new pa_protocol_native_new - #define protocol_free pa_protocol_native_free - #define TCPWRAP_SERVICE "pulseaudio-native" - #define IPV4_PORT PA_NATIVE_DEFAULT_PORT - #define UNIX_SOCKET PA_NATIVE_DEFAULT_UNIX_SOCKET - #define MODULE_ARGUMENTS_COMMON "cookie", "auth-anonymous", - #ifdef USE_TCP_SOCKETS - #include "module-native-protocol-tcp-symdef.h" - #else - #include "module-native-protocol-unix-symdef.h" - #endif - - #if defined(HAVE_CREDS) && !defined(USE_TCP_SOCKETS) - #define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-group", "auth-group-enable", - #define AUTH_USAGE "auth-group= auth-group-enable= " - #elif defined(USE_TCP_SOCKETS) - #define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-ip-acl", - #define AUTH_USAGE "auth-ip-acl= " - #else - #define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON - #define AUTH_USAGE - #endif +# include +# define TCPWRAP_SERVICE "pulseaudio-native" +# define IPV4_PORT PA_NATIVE_DEFAULT_PORT +# define UNIX_SOCKET PA_NATIVE_DEFAULT_UNIX_SOCKET +# define MODULE_ARGUMENTS_COMMON "cookie", "auth-cookie", "auth-cookie-enabled", "auth-anonymous", + +# ifdef USE_TCP_SOCKETS +# include "module-native-protocol-tcp-symdef.h" +# else +# include "module-native-protocol-unix-symdef.h" +# endif + +# if defined(HAVE_CREDS) && !defined(USE_TCP_SOCKETS) +# define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-group", "auth-group-enable", +# define AUTH_USAGE "auth-group= auth-group-enable= " +# elif defined(USE_TCP_SOCKETS) +# define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-ip-acl", +# define AUTH_USAGE "auth-ip-acl= " +# else +# define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON +# define AUTH_USAGE +# endif PA_MODULE_DESCRIPTION("Native protocol "SOCKET_DESCRIPTION); PA_MODULE_USAGE("auth-anonymous= " - "cookie= " + "auth-cookie= " + "auth-cookie-enabled= - #include - #define protocol_new pa_protocol_esound_new - #define protocol_free pa_protocol_esound_free - #define TCPWRAP_SERVICE "esound" - #define IPV4_PORT ESD_DEFAULT_PORT - #define MODULE_ARGUMENTS_COMMON "sink", "source", "auth-anonymous", "cookie", - #ifdef USE_TCP_SOCKETS - #include "module-esound-protocol-tcp-symdef.h" - #else - #include "module-esound-protocol-unix-symdef.h" - #endif - - #if defined(USE_TCP_SOCKETS) - #define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-ip-acl", - #define AUTH_USAGE "auth-ip-acl= " - #else - #define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON - #define AUTH_USAGE - #endif +# include +# include +# define TCPWRAP_SERVICE "esound" +# define IPV4_PORT ESD_DEFAULT_PORT +# define MODULE_ARGUMENTS_COMMON "sink", "source", "auth-anonymous", "cookie", "auth-cookie", "auth-cookie-enabled" + +# ifdef USE_TCP_SOCKETS +# include "module-esound-protocol-tcp-symdef.h" +# else +# include "module-esound-protocol-unix-symdef.h" +# endif + +# if defined(USE_TCP_SOCKETS) +# define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-ip-acl", +# define AUTH_USAGE "auth-ip-acl= " +# else +# define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON +# define AUTH_USAGE +# endif PA_MODULE_DESCRIPTION("ESOUND protocol "SOCKET_DESCRIPTION); PA_MODULE_USAGE("sink= " "source= " "auth-anonymous= " - "cookie= " + "auth-cookie= " + "auth-cookie-enabled=simple_protocol, io, u->simple_options); +#elif defined(USE_PROTOCOL_CLI) + pa_cli_protocol_connect(u->cli_protocol, io, u->module); +#elif defined(USE_PROTOCOL_HTTP) + pa_http_protocol_connect(u->http_protocol, io, u->module); +#elif defined(USE_PROTOCOL_NATIVE) + pa_native_protocol_connect(u->native_protocol, io, u->native_options); +#else + pa_esound_protocol_connect(u->esound_protocol, io, u->esound_options); +#endif +} + int pa__init(pa_module*m) { pa_modargs *ma = NULL; - int ret = -1; struct userdata *u = NULL; #if defined(USE_TCP_SOCKETS) - pa_socket_server *s_ipv4 = NULL, *s_ipv6 = NULL; uint32_t port = IPV4_PORT; const char *listen_on; #else - pa_socket_server *s; int r; #endif +#if defined(USE_PROTOCOL_NATIVE) + char t[256]; +#endif + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); - goto finish; + goto fail; } u = pa_xnew0(struct userdata, 1); + u->module = m; + +#if defined(USE_PROTOCOL_SIMPLE) + u->simple_protocol = pa_simple_protocol_get(m->core); + + u->simple_options = pa_simple_options_new(); + if (pa_simple_options_parse(u->simple_options, m->core, ma) < 0) + goto fail; + u->simple_options->module = m; +#elif defined(USE_PROTOCOL_CLI) + u->cli_protocol = pa_cli_protocol_get(m->core); +#elif defined(USE_PROTOCOL_HTTP) + u->http_protocol = pa_http_protocol_get(m->core); +#elif defined(USE_PROTOCOL_NATIVE) + u->native_protocol = pa_native_protocol_get(m->core); + + u->native_options = pa_native_options_new(); + if (pa_native_options_parse(u->native_options, m->core, ma) < 0) + goto fail; + u->native_options->module = m; +#else + u->esound_protocol = pa_esound_protocol_get(m->core); + + u->esound_options = pa_esound_options_new(); + if (pa_esound_options_parse(u->esound_options, m->core, ma) < 0) + goto fail; + u->esound_options->module = m; +#endif #if defined(USE_TCP_SOCKETS) if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port < 1 || port > 0xFFFF) { @@ -233,38 +299,30 @@ int pa__init(pa_module*m) { listen_on = pa_modargs_get_value(ma, "listen", NULL); if (listen_on) { - s_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE); - s_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE); + u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE); + u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE); } else { - s_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, port, TCPWRAP_SERVICE); - s_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, port, TCPWRAP_SERVICE); + u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, port, TCPWRAP_SERVICE); + u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, port, TCPWRAP_SERVICE); } - if (!s_ipv4 && !s_ipv6) + if (!u->socket_server_ipv4 && !u->socket_server_ipv6) goto fail; - if (s_ipv4) - u->protocol_ipv4 = protocol_new(m->core, s_ipv4, m, ma); - if (s_ipv6) - u->protocol_ipv6 = protocol_new(m->core, s_ipv6, m, ma); - - if (!u->protocol_ipv4 && !u->protocol_ipv6) - goto fail; - - if (s_ipv6) - pa_socket_server_unref(s_ipv6); - if (s_ipv6) - pa_socket_server_unref(s_ipv4); + if (u->socket_server_ipv4) + pa_socket_server_set_callback(u->socket_server_ipv4, socket_server_on_connection_cb, u); + if (u->socket_server_ipv6) + pa_socket_server_set_callback(u->socket_server_ipv6, socket_server_on_connection_cb, u); #else -#if defined(USE_PROTOCOL_ESOUND) +# if defined(USE_PROTOCOL_ESOUND) -#if defined(USE_PER_USER_ESOUND_SOCKET) +# if defined(USE_PER_USER_ESOUND_SOCKET) u->socket_path = pa_sprintf_malloc("/tmp/.esd-%lu/socket", (unsigned long) getuid()); -#else +# else u->socket_path = pa_xstrdup("/tmp/.esd/socket"); -#endif +# endif /* This socket doesn't reside in our own runtime dir but in * /tmp/.esd/, hence we have to create the dir first */ @@ -274,12 +332,12 @@ int pa__init(pa_module*m) { goto fail; } -#else +# else if (!(u->socket_path = pa_runtime_path(pa_modargs_get_value(ma, "socket", UNIX_SOCKET)))) { pa_log("Failed to generate socket path."); goto fail; } -#endif +# endif if ((r = pa_unix_socket_remove_stale(u->socket_path)) < 0) { pa_log("Failed to remove stale UNIX socket '%s': %s", u->socket_path, pa_cstrerror(errno)); @@ -287,53 +345,44 @@ int pa__init(pa_module*m) { } else if (r > 0) pa_log_info("Removed stale UNIX socket '%s'.", u->socket_path); - if (!(s = pa_socket_server_new_unix(m->core->mainloop, u->socket_path))) + if (!(u->socket_server_unix = pa_socket_server_new_unix(m->core->mainloop, u->socket_path))) goto fail; - if (!(u->protocol_unix = protocol_new(m->core, s, m, ma))) - goto fail; + pa_socket_server_set_callback(u->socket_server_unix, socket_server_on_connection_cb, u); - pa_socket_server_unref(s); +#endif + +#if defined(USE_PROTOCOL_NATIVE) +# if defined(USE_TCP_SOCKETS) + if (u->socket_server_ipv4) + if (pa_socket_server_get_address(u->socket_server_ipv4, t, sizeof(t))) + pa_native_protocol_add_server_string(u->native_protocol, t); + + if (u->socket_server_ipv6) + if (pa_socket_server_get_address(u->socket_server_ipv6, t, sizeof(t))) + pa_native_protocol_add_server_string(u->native_protocol, t); +# else + if (pa_socket_server_get_address(u->socket_server_unix, t, sizeof(t))) + pa_native_protocol_add_server_string(u->native_protocol, t); +# endif #endif m->userdata = u; - ret = 0; - -finish: if (ma) pa_modargs_free(ma); - return ret; + return 0; fail: - if (u) { -#if defined(USE_TCP_SOCKETS) - if (u->protocol_ipv4) - protocol_free(u->protocol_ipv4); - if (u->protocol_ipv6) - protocol_free(u->protocol_ipv6); -#else - if (u->protocol_unix) - protocol_free(u->protocol_unix); - pa_xfree(u->socket_path); -#endif - pa_xfree(u); - } + if (ma) + pa_modargs_free(ma); -#if defined(USE_TCP_SOCKETS) - if (s_ipv4) - pa_socket_server_unref(s_ipv4); - if (s_ipv6) - pa_socket_server_unref(s_ipv6); -#else - if (s) - pa_socket_server_unref(s); -#endif + pa__done(m); - goto finish; + return -1; } void pa__done(pa_module*m) { @@ -343,22 +392,72 @@ void pa__done(pa_module*m) { u = m->userdata; +#if defined(USE_PROTOCOL_SIMPLE) + if (u->simple_protocol) { + pa_simple_protocol_disconnect(u->simple_protocol, u->module); + pa_simple_protocol_unref(u->simple_protocol); + } + if (u->simple_options) + pa_simple_options_unref(u->simple_options); +#elif defined(USE_PROTOCOL_CLI) + if (u->cli_protocol) { + pa_cli_protocol_disconnect(u->cli_protocol, u->module); + pa_cli_protocol_unref(u->cli_protocol); + } +#elif defined(USE_PROTOCOL_HTTP) + if (u->http_protocol) { + pa_http_protocol_disconnect(u->http_protocol, u->module); + pa_http_protocol_unref(u->http_protocol); + } +#elif defined(USE_PROTOCOL_NATIVE) + if (u->native_protocol) { + + char t[256]; + +# if defined(USE_TCP_SOCKETS) + if (u->socket_server_ipv4) + if (pa_socket_server_get_address(u->socket_server_ipv4, t, sizeof(t))) + pa_native_protocol_remove_server_string(u->native_protocol, t); + + if (u->socket_server_ipv6) + if (pa_socket_server_get_address(u->socket_server_ipv6, t, sizeof(t))) + pa_native_protocol_remove_server_string(u->native_protocol, t); +# else + if (u->socket_server_unix) + if (pa_socket_server_get_address(u->socket_server_unix, t, sizeof(t))) + pa_native_protocol_remove_server_string(u->native_protocol, t); +# endif + + pa_native_protocol_disconnect(u->native_protocol, u->module); + pa_native_protocol_unref(u->native_protocol); + } + if (u->native_options) + pa_native_options_unref(u->native_options); +#else + if (u->esound_protocol) { + pa_esound_protocol_disconnect(u->esound_protocol, u->module); + pa_esound_protocol_unref(u->esound_protocol); + } + if (u->esound_options) + pa_esound_options_unref(u->esound_options); +#endif + #if defined(USE_TCP_SOCKETS) - if (u->protocol_ipv4) - protocol_free(u->protocol_ipv4); - if (u->protocol_ipv6) - protocol_free(u->protocol_ipv6); + if (u->socket_server_ipv4) + pa_socket_server_unref(u->socket_server_ipv4); + if (u->socket_server_ipv6) + pa_socket_server_unref(u->socket_server_ipv6); #else - if (u->protocol_unix) - protocol_free(u->protocol_unix); + if (u->socket_server_unix) + pa_socket_server_unref(u->socket_server_unix); -#if defined(USE_PROTOCOL_ESOUND) && !defined(USE_PER_USER_ESOUND_SOCKET) +# if defined(USE_PROTOCOL_ESOUND) && !defined(USE_PER_USER_ESOUND_SOCKET) if (u->socket_path) { char *p = pa_parent_dir(u->socket_path); rmdir(p); pa_xfree(p); } -#endif +# endif pa_xfree(u->socket_path); #endif diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 21f2f842..af27ce74 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -45,16 +45,15 @@ #include #include #include -#include #include #include -#include #include #include #include #include #include #include +#include #ifdef TUNNEL_SINK #include "module-tunnel-sink-symdef.h" @@ -185,7 +184,7 @@ struct userdata { pa_source *source; #endif - uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH]; + pa_auth_cookie *auth_cookie; uint32_t version; uint32_t ctag; @@ -204,8 +203,6 @@ struct userdata { pa_time_event *time_event; - pa_bool_t auth_cookie_in_property; - pa_smoother *smoother; char *device_description; @@ -1588,7 +1585,8 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata pa_tagstruct_putu32(t, PA_COMMAND_AUTH); pa_tagstruct_putu32(t, tag = u->ctag++); pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION); - pa_tagstruct_put_arbitrary(t, u->auth_cookie, sizeof(u->auth_cookie)); + + pa_tagstruct_put_arbitrary(t, pa_auth_cookie_read(u->auth_cookie, PA_NATIVE_COOKIE_LENGTH), PA_NATIVE_COOKIE_LENGTH); #ifdef HAVE_CREDS { @@ -1658,33 +1656,6 @@ static int sink_set_mute(pa_sink *sink) { #endif -/* Called from main context */ -static int load_key(struct userdata *u, const char*fn) { - pa_assert(u); - - u->auth_cookie_in_property = FALSE; - - if (!fn && pa_authkey_prop_get(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) { - pa_log_debug("Using already loaded auth cookie."); - pa_authkey_prop_ref(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME); - u->auth_cookie_in_property = 1; - return 0; - } - - if (!fn) - fn = PA_NATIVE_COOKIE_FILE; - - if (pa_authkey_load_auto(fn, u->auth_cookie, sizeof(u->auth_cookie)) < 0) - return -1; - - pa_log_debug("Loading cookie from disk."); - - if (pa_authkey_prop_put(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) - u->auth_cookie_in_property = TRUE; - - return 0; -} - int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u = NULL; @@ -1722,7 +1693,6 @@ int pa__init(pa_module*m) { u->smoother = pa_smoother_new(PA_USEC_PER_SEC, PA_USEC_PER_SEC*2, TRUE, 10); u->ctag = 1; u->device_index = u->channel = PA_INVALID_INDEX; - u->auth_cookie_in_property = FALSE; u->time_event = NULL; u->ignore_latency_before = 0; u->transport_usec = 0; @@ -1733,7 +1703,7 @@ int pa__init(pa_module*m) { u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); - if (load_key(u, pa_modargs_get_value(ma, "cookie", NULL)) < 0) + if (!(u->auth_cookie = pa_auth_cookie_get(u->core, pa_modargs_get_value(ma, "cookie", PA_NATIVE_COOKIE_FILE), PA_NATIVE_COOKIE_LENGTH))) goto fail; if (!(u->server_name = pa_xstrdup(pa_modargs_get_value(ma, "server", NULL)))) { @@ -1911,8 +1881,8 @@ void pa__done(pa_module*m) { if (u->client) pa_socket_client_unref(u->client); - if (u->auth_cookie_in_property) - pa_authkey_prop_unref(m->core, PA_NATIVE_COOKIE_PROPERTY_NAME); + if (u->auth_cookie) + pa_auth_cookie_unref(u->auth_cookie); if (u->smoother) pa_smoother_free(u->smoother); diff --git a/src/modules/module-x11-publish.c b/src/modules/module-x11-publish.c index 4ef4873a..c29535e6 100644 --- a/src/modules/module-x11-publish.c +++ b/src/modules/module-x11-publish.c @@ -43,11 +43,11 @@ #include #include #include -#include -#include +#include #include #include #include +#include #include "module-x11-publish-symdef.h" @@ -68,15 +68,48 @@ static const char* const valid_modargs[] = { struct userdata { pa_core *core; pa_module *module; + pa_native_protocol *protocol; char *id; - uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH]; - pa_bool_t auth_cookie_in_property; + pa_auth_cookie *auth_cookie; pa_x11_wrapper *x11_wrapper; pa_x11_client *x11_client; + + pa_hook_slot *hook_slot; }; +static void publish_servers(struct userdata *u, pa_strlist *l) { + + if (l) { + char *s; + + l = pa_strlist_reverse(l); + s = pa_strlist_tostring(l); + l = pa_strlist_reverse(l); + + pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SERVER", s); + pa_xfree(s); + } else + pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SERVER"); +} + +static pa_hook_result_t servers_changed_cb(void *hook_data, void *call_data, void *slot_data) { + pa_strlist *servers = call_data; + struct userdata *u = slot_data; + char t[256]; + + pa_assert(u); + + if (!pa_x11_get_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_ID", t, sizeof(t)) || strcmp(t, u->id)) { + pa_log_warn("PulseAudio information vanished from X11!"); + return PA_HOOK_OK; + } + + publish_servers(u, servers); + return PA_HOOK_OK; +} + static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) { struct userdata *u = userdata; @@ -96,40 +129,12 @@ static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) { pa_module_unload_request(u->module); } -static int load_key(struct userdata *u, const char*fn) { - pa_assert(u); - - u->auth_cookie_in_property = FALSE; - - if (!fn && pa_authkey_prop_get(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) { - pa_log_debug("using already loaded auth cookie."); - pa_authkey_prop_ref(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME); - u->auth_cookie_in_property = 1; - return 0; - } - - if (!fn) - fn = PA_NATIVE_COOKIE_FILE; - - if (pa_authkey_load_auto(fn, u->auth_cookie, sizeof(u->auth_cookie)) < 0) - return -1; - - pa_log_debug("Loading cookie from disk."); - - if (pa_authkey_prop_put(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) - u->auth_cookie_in_property = TRUE; - - return 0; -} - int pa__init(pa_module*m) { struct userdata *u; pa_modargs *ma = NULL; char hn[256], un[128]; char hx[PA_NATIVE_COOKIE_LENGTH*2+1]; const char *t; - char *s; - pa_strlist *l; pa_assert(m); @@ -141,40 +146,36 @@ int pa__init(pa_module*m) { m->userdata = u = pa_xnew(struct userdata, 1); u->core = m->core; u->module = m; + u->protocol = pa_native_protocol_get(m->core); u->id = NULL; - u->auth_cookie_in_property = FALSE; + u->auth_cookie = NULL; u->x11_client = NULL; u->x11_wrapper = NULL; - if (load_key(u, pa_modargs_get_value(ma, "cookie", NULL)) < 0) - goto fail; + u->hook_slot = pa_hook_connect(pa_native_protocol_servers_changed(u->protocol), PA_HOOK_NORMAL, servers_changed_cb, u); - if (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL)))) + if (!(u->auth_cookie = pa_auth_cookie_get(m->core, pa_modargs_get_value(ma, "cookie", PA_NATIVE_COOKIE_FILE), PA_NATIVE_COOKIE_LENGTH))) goto fail; - if (!(l = pa_shared_get(m->core, PA_NATIVE_SERVER_PROPERTY_NAME))) + if (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL)))) goto fail; - l = pa_strlist_reverse(l); - s = pa_strlist_tostring(l); - l = pa_strlist_reverse(l); - - pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SERVER", s); - pa_xfree(s); - if (!pa_get_fqdn(hn, sizeof(hn)) || !pa_get_user_name(un, sizeof(un))) goto fail; u->id = pa_sprintf_malloc("%s@%s/%u", un, hn, (unsigned) getpid()); pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_ID", u->id); + publish_servers(u, pa_native_protocol_servers(u->protocol)); + if ((t = pa_modargs_get_value(ma, "source", NULL))) pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SOURCE", t); if ((t = pa_modargs_get_value(ma, "sink", NULL))) pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SINK", t); - pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_COOKIE", pa_hexstr(u->auth_cookie, sizeof(u->auth_cookie), hx, sizeof(hx))); + pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_COOKIE", + pa_hexstr(pa_auth_cookie_read(u->auth_cookie, PA_NATIVE_COOKIE_LENGTH), PA_NATIVE_COOKIE_LENGTH, hx, sizeof(hx))); u->x11_client = pa_x11_client_new(u->x11_wrapper, NULL, x11_kill_cb, u); @@ -220,8 +221,14 @@ void pa__done(pa_module*m) { pa_x11_wrapper_unref(u->x11_wrapper); } - if (u->auth_cookie_in_property) - pa_authkey_prop_unref(m->core, PA_NATIVE_COOKIE_PROPERTY_NAME); + if (u->auth_cookie) + pa_auth_cookie_unref(u->auth_cookie); + + if (u->hook_slot) + pa_hook_slot_free(u->hook_slot); + + if (u->protocol) + pa_native_protocol_unref(u->protocol); pa_xfree(u->id); pa_xfree(u); -- cgit