diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 36 | ||||
-rw-r--r-- | src/daemon/main.c | 32 | ||||
-rw-r--r-- | src/modules/bluetooth/bluetooth-util.c | 2 | ||||
-rw-r--r-- | src/modules/bluetooth/module-bluetooth-device.c | 3 | ||||
-rw-r--r-- | src/modules/bluetooth/module-bluetooth-discover.c | 2 | ||||
-rw-r--r-- | src/modules/bluetooth/module-bluetooth-proximity.c | 2 | ||||
-rw-r--r-- | src/modules/hal-util.c | 2 | ||||
-rw-r--r-- | src/modules/module-console-kit.c | 2 | ||||
-rw-r--r-- | src/modules/module-hal-detect.c | 2 | ||||
-rw-r--r-- | src/modules/reserve-wrap.c | 3 | ||||
-rw-r--r-- | src/pulse/context.c | 79 | ||||
-rw-r--r-- | src/pulse/context.h | 7 | ||||
-rw-r--r-- | src/pulse/def.h | 5 | ||||
-rw-r--r-- | src/pulse/internal.h | 5 | ||||
-rw-r--r-- | src/pulsecore/dbus-shared.c | 111 | ||||
-rw-r--r-- | src/pulsecore/dbus-shared.h | 42 | ||||
-rw-r--r-- | src/pulsecore/dbus-util.c (renamed from src/modules/dbus-util.c) | 116 | ||||
-rw-r--r-- | src/pulsecore/dbus-util.h (renamed from src/modules/dbus-util.h) | 17 | ||||
-rw-r--r-- | src/tests/gtk-test.c | 41 |
19 files changed, 379 insertions, 130 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a99e2756..0d4f53af 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -633,6 +633,12 @@ if OS_IS_WIN32 libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/dllmain.c endif +if HAVE_DBUS +libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/dbus-util.c pulsecore/dbus-util.h +libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(DBUS_CFLAGS) +libpulsecommon_@PA_MAJORMINORMICRO@_la_LIBADD += $(DBUS_LIBS) +endif + ################################### # Client library # ################################### @@ -713,7 +719,7 @@ libpulse_la_SOURCES = \ pulse/volume.c pulse/volume.h \ pulse/xmalloc.c pulse/xmalloc.h -libpulse_la_CFLAGS = $(AM_CFLAGS) +libpulse_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LTLIBICONV) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_VERSION_INFO) @@ -813,6 +819,13 @@ libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS += $(X11_CFLAGS) libpulsecore_@PA_MAJORMINORMICRO@_la_LDFLAGS += $(X11_LIBS) endif + +if HAVE_DBUS +libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/dbus-shared.c pulsecore/dbus-shared.h +libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS += $(DBUS_CFLAGS) +libpulsecore_@PA_MAJORMINORMICRO@_la_LIBADD += $(DBUS_LIBS) +endif + # We split the foreign code off to not be annoyed by warnings we don't care about noinst_LTLIBRARIES = libpulsecore-foreign.la @@ -902,7 +915,6 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMIN if HAVE_DBUS # Serveral module (e.g. libalsa-util.la) modlibexec_LTLIBRARIES += \ - libdbus-util.la \ module-console-kit.la endif @@ -1322,7 +1334,7 @@ endif if HAVE_DBUS libalsa_util_la_SOURCES += modules/reserve.h modules/reserve.c modules/reserve-wrap.c modules/reserve-wrap.h -libalsa_util_la_LIBADD += $(DBUS_LIBS) libdbus-util.la +libalsa_util_la_LIBADD += $(DBUS_LIBS) libalsa_util_la_CFLAGS += $(DBUS_CFLAGS) endif @@ -1476,20 +1488,14 @@ module_jack_source_la_LDFLAGS = $(MODULE_LDFLAGS) module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la $(JACK_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la module_jack_source_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) -# HAL/D-Bus -libdbus_util_la_SOURCES = modules/dbus-util.c modules/dbus-util.h -libdbus_util_la_LDFLAGS = -avoid-version -libdbus_util_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la -libdbus_util_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) - module_hal_detect_la_SOURCES = modules/module-hal-detect.c module_hal_detect_la_LDFLAGS = $(MODULE_LDFLAGS) -module_hal_detect_la_LIBADD = $(AM_LIBADD) $(HAL_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libdbus-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la +module_hal_detect_la_LIBADD = $(AM_LIBADD) $(HAL_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la module_hal_detect_la_CFLAGS = $(AM_CFLAGS) $(HAL_CFLAGS) module_console_kit_la_SOURCES = modules/module-console-kit.c module_console_kit_la_LDFLAGS = $(MODULE_LDFLAGS) -module_console_kit_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libdbus-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la +module_console_kit_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la module_console_kit_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) # GConf support @@ -1506,7 +1512,7 @@ gconf_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) # Bluetooth proximity module_bluetooth_proximity_la_SOURCES = modules/bluetooth/module-bluetooth-proximity.c module_bluetooth_proximity_la_LDFLAGS = $(MODULE_LDFLAGS) -module_bluetooth_proximity_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libdbus-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la +module_bluetooth_proximity_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la module_bluetooth_proximity_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -DPA_BT_PROXIMITY_HELPER=\"$(pulselibexecdir)/proximity-helper\" proximity_helper_SOURCES = modules/bluetooth/proximity-helper.c @@ -1517,7 +1523,7 @@ proximity_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) # Bluetooth sink / source module_bluetooth_discover_la_SOURCES = modules/bluetooth/module-bluetooth-discover.c module_bluetooth_discover_la_LDFLAGS = $(MODULE_LDFLAGS) -module_bluetooth_discover_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libdbus-util.la libbluetooth-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la +module_bluetooth_discover_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libbluetooth-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la module_bluetooth_discover_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) libbluetooth_sbc_la_SOURCES = modules/bluetooth/sbc.c modules/bluetooth/sbc.h modules/bluetooth/sbc_tables.h modules/bluetooth/sbc_math.h modules/bluetooth/sbc_primitives.h modules/bluetooth/sbc_primitives.c modules/bluetooth/sbc_primitives_mmx.h modules/bluetooth/sbc_primitives_neon.h modules/bluetooth/sbc_primitives_mmx.c modules/bluetooth/sbc_primitives_neon.c @@ -1534,12 +1540,12 @@ BLUETOOTH_IPC_FILES = $(subst modules/bluetooth/,,$(libbluetooth_ipc_la_SOURCES) libbluetooth_util_la_SOURCES = modules/bluetooth/bluetooth-util.c modules/bluetooth/bluetooth-util.h libbluetooth_util_la_LDFLAGS = -avoid-version -libbluetooth_util_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libdbus-util.la +libbluetooth_util_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libbluetooth_util_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) module_bluetooth_device_la_SOURCES = modules/bluetooth/module-bluetooth-device.c modules/bluetooth/rtp.h module_bluetooth_device_la_LDFLAGS = $(MODULE_LDFLAGS) -module_bluetooth_device_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libdbus-util.la libbluetooth-util.la libbluetooth-ipc.la libbluetooth-sbc.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la +module_bluetooth_device_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libbluetooth-util.la libbluetooth-ipc.la libbluetooth-sbc.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la module_bluetooth_device_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) # Apple Airtunes/RAOP diff --git a/src/daemon/main.c b/src/daemon/main.c index 47ca2673..1d543481 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -87,6 +87,9 @@ #include <pulsecore/thread.h> #include <pulsecore/once.h> #include <pulsecore/shm.h> +#ifdef HAVE_DBUS +#include <pulsecore/dbus-shared.h> +#endif #include "cmdline.h" #include "cpulimit.h" @@ -330,6 +333,31 @@ static void set_all_rlimits(const pa_daemon_conf *conf) { } #endif +#ifdef HAVE_DBUS +static void register_org_pulseaudio(pa_core *c) +{ + DBusError error; + pa_dbus_connection *conn; + + dbus_error_init(&error); + if (!(conn = pa_dbus_bus_get(c, pa_in_system_mode() ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) { + pa_log_warn("Unable to contact DBUS: %s: %s", error.name, error.message); + goto finish_dbus; + } + + if (dbus_bus_request_name (pa_dbus_connection_get(conn), "org.pulseaudio", 0, &error) == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) + pa_log_debug("Got org.pulseaudio!"); + else if (dbus_error_is_set(&error)) + pa_log_warn("Unable to get org.pulseaudio: %s: %s", error.name, error.message); + +finish_dbus: + if (conn) + pa_dbus_connection_unref(conn); + + dbus_error_free(&error); +} +#endif + int main(int argc, char *argv[]) { pa_core *c = NULL; pa_strbuf *buf = NULL; @@ -997,6 +1025,10 @@ int main(int argc, char *argv[]) { } #endif +#ifdef HAVE_DBUS + register_org_pulseaudio(c); +#endif + pa_log_info(_("Daemon startup complete.")); retval = 0; diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 3dfc65e7..1cdade99 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -25,7 +25,7 @@ #include <pulsecore/core-util.h> #include <pulsecore/shared.h> -#include <modules/dbus-util.h> +#include <pulsecore/dbus-shared.h> #include "bluetooth-util.h" diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 2500fb09..2ff64ba9 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -46,8 +46,7 @@ #include <pulsecore/time-smoother.h> #include <pulsecore/rtclock.h> #include <pulsecore/namereg.h> - -#include <modules/dbus-util.h> +#include <pulsecore/dbus-shared.h> #include "module-bluetooth-device-symdef.h" #include "ipc.h" diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c index 3288cc55..46f8b723 100644 --- a/src/modules/bluetooth/module-bluetooth-discover.c +++ b/src/modules/bluetooth/module-bluetooth-discover.c @@ -34,7 +34,7 @@ #include <pulsecore/macro.h> #include <pulsecore/llist.h> #include <pulsecore/core-util.h> -#include <modules/dbus-util.h> +#include <pulsecore/dbus-shared.h> #include "module-bluetooth-discover-symdef.h" #include "bluetooth-util.h" diff --git a/src/modules/bluetooth/module-bluetooth-proximity.c b/src/modules/bluetooth/module-bluetooth-proximity.c index c8d7b4d9..9993c8dc 100644 --- a/src/modules/bluetooth/module-bluetooth-proximity.c +++ b/src/modules/bluetooth/module-bluetooth-proximity.c @@ -42,8 +42,8 @@ #include <pulsecore/core-util.h> #include <pulsecore/core-error.h> #include <pulsecore/start-child.h> +#include <pulsecore/dbus-shared.h> -#include "../dbus-util.h" #include "module-bluetooth-proximity-symdef.h" PA_MODULE_AUTHOR("Lennart Poettering"); diff --git a/src/modules/hal-util.c b/src/modules/hal-util.c index 422ae4ec..e2a2d8d7 100644 --- a/src/modules/hal-util.c +++ b/src/modules/hal-util.c @@ -24,10 +24,10 @@ #endif #include <pulsecore/log.h> +#include <pulsecore/dbus-shared.h> #include <hal/libhal.h> -#include "dbus-util.h" #include "hal-util.h" int pa_hal_get_info(pa_core *core, pa_proplist *p, int card) { diff --git a/src/modules/module-console-kit.c b/src/modules/module-console-kit.c index 3fba7ef6..a666073c 100644 --- a/src/modules/module-console-kit.c +++ b/src/modules/module-console-kit.c @@ -44,8 +44,8 @@ #include <pulsecore/namereg.h> #include <pulsecore/core-scache.h> #include <pulsecore/modargs.h> +#include <pulsecore/dbus-shared.h> -#include "dbus-util.h" #include "module-console-kit-symdef.h" PA_MODULE_AUTHOR("Lennart Poettering"); diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 9b0d71c9..0dd22cbd 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -45,10 +45,10 @@ #include <pulsecore/namereg.h> #include <pulsecore/core-scache.h> #include <pulsecore/modargs.h> +#include <pulsecore/dbus-shared.h> #include <hal/libhal.h> -#include "dbus-util.h" #include "module-hal-detect-symdef.h" PA_MODULE_AUTHOR("Shahms King"); diff --git a/src/modules/reserve-wrap.c b/src/modules/reserve-wrap.c index c956673b..1927342b 100644 --- a/src/modules/reserve-wrap.c +++ b/src/modules/reserve-wrap.c @@ -29,8 +29,7 @@ #include <pulsecore/core-error.h> #include <pulsecore/core-util.h> #include <pulsecore/shared.h> - -#include <modules/dbus-util.h> +#include <pulsecore/dbus-shared.h> #include "reserve.h" #include "reserve-wrap.h" diff --git a/src/pulse/context.c b/src/pulse/context.c index 7c86a435..9fb9e726 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -104,6 +104,7 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED] = pa_command_stream_buffer_attr }; static void context_free(pa_context *c); +static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata); pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) { return pa_context_new_with_proplist(mainloop, name, NULL); @@ -143,6 +144,8 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * if (name) pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name); + c->no_fail = FALSE; + c->system_bus = c->session_bus = NULL; c->mainloop = mainloop; c->client = NULL; c->pstream = NULL; @@ -237,6 +240,16 @@ static void context_free(pa_context *c) { context_unlink(c); + if (c->system_bus) { + dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c); + pa_dbus_wrap_connection_free(c->system_bus); + } + + if (c->session_bus) { + dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c); + pa_dbus_wrap_connection_free(c->session_bus); + } + if (c->record_streams) pa_dynarray_free(c->record_streams, NULL, NULL); if (c->playback_streams) @@ -728,6 +741,32 @@ fail: static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata); +static void track_pulseaudio_on_dbus(pa_context *c, DBusBusType type, pa_dbus_wrap_connection **conn) { + DBusError error; + + pa_assert(c); + pa_assert(conn); + + dbus_error_init(&error); + if (!(*conn = pa_dbus_wrap_connection_new(c->mainloop, type, &error)) || dbus_error_is_set(&error)) { + pa_log_warn("Unable to contact DBUS: %s: %s", error.name, error.message); + goto finish; + } + + if (!dbus_connection_add_filter(pa_dbus_wrap_connection_get(*conn), filter_cb, c, NULL)) { + pa_log_warn("Failed to add filter function"); + goto finish; + } + + if (pa_dbus_add_matches( + pa_dbus_wrap_connection_get(*conn), &error, + "type='signal',sender='" DBUS_SERVICE_DBUS "',interface='" DBUS_INTERFACE_DBUS "',member='NameOwnerChanged',arg0='org.pulseaudio',arg1=''", NULL) < 0) + pa_log_warn("Unable to track org.pulseaudio: %s: %s", error.name, error.message); + + finish: + dbus_error_free(&error); +} + static int try_next_connection(pa_context *c) { char *u = NULL; int r = -1; @@ -760,7 +799,14 @@ static int try_next_connection(pa_context *c) { } #endif - pa_context_fail(c, PA_ERR_CONNECTIONREFUSED); + if (c->no_fail) { + if (!c->system_bus) + track_pulseaudio_on_dbus(c, DBUS_BUS_SYSTEM, &c->system_bus); + if (!c->session_bus) + track_pulseaudio_on_dbus(c, DBUS_BUS_SESSION, &c->session_bus); + } else + pa_context_fail(c, PA_ERR_CONNECTIONREFUSED); + goto finish; } @@ -817,6 +863,34 @@ finish: pa_context_unref(c); } +static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) { + pa_context *c = userdata; + pa_bool_t is_session; + + pa_assert(bus); + pa_assert(message); + pa_assert(c); + + if (c->state != PA_CONTEXT_CONNECTING) + goto finish; + + is_session = bus == pa_dbus_wrap_connection_get(c->session_bus); + pa_log_debug("Rock!! PulseAudio is baack on %s bus", is_session ? "session" : "system"); + + if (is_session) { + /* The user instance via PF_LOCAL */ + c->server_list = prepend_per_user(c->server_list); + } else { + /* The system wide instance via PF_LOCAL */ + c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET); + } + + try_next_connection(c); + +finish: + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + int pa_context_connect( pa_context *c, const char *server, @@ -830,7 +904,7 @@ int pa_context_connect( PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED); PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE); - PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID); + PA_CHECK_VALIDITY(c, !(flags & ~(PA_CONTEXT_NOAUTOSPAWN|PA_CONTEXT_NOFAIL)), PA_ERR_INVALID); PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID); if (!server) @@ -838,6 +912,7 @@ int pa_context_connect( pa_context_ref(c); + c->no_fail = flags & PA_CONTEXT_NOFAIL; pa_assert(!c->server_list); if (server) { diff --git a/src/pulse/context.h b/src/pulse/context.h index c32cf443..139d0e0b 100644 --- a/src/pulse/context.h +++ b/src/pulse/context.h @@ -207,9 +207,10 @@ pa_context_state_t pa_context_get_state(pa_context *c); connect to the default server. This routine may but will not always return synchronously on error. Use pa_context_set_state_callback() to be notified when the connection is established. If flags doesn't have -PA_NOAUTOSPAWN set and no specific server is specified or accessible a -new daemon is spawned. If api is non-NULL, the functions specified in -the structure are used when forking a new child process. */ +PA_CONTEXT_NOAUTOSPAWN set and no specific server is specified or +accessible a new daemon is spawned. If api is non-NULL, the functions +specified in the structure are used when forking a new child +process. */ int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api); /** Terminate the context connection immediately */ diff --git a/src/pulse/def.h b/src/pulse/def.h index 9928f9bd..cae08942 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -109,13 +109,16 @@ typedef enum pa_operation_state { /** Some special flags for contexts. */ typedef enum pa_context_flags { - PA_CONTEXT_NOAUTOSPAWN = 1 + PA_CONTEXT_NOAUTOSPAWN = 0x0001U, /**< Disabled autospawning of the PulseAudio daemon if required */ + PA_CONTEXT_NOFAIL = 0x0002U + /**< Don't fail if the daemon is not available when pa_context_connect() is called, instead enter PA_CONTEXT_CONNECTING state and wait for the daemon to appear. \since 0.9.15 */ } pa_context_flags_t; /** \cond fulldocs */ /* Allow clients to check with #ifdef for those flags */ #define PA_CONTEXT_NOAUTOSPAWN PA_CONTEXT_NOAUTOSPAWN +#define PA_CONTEXT_NOFAIL PA_CONTEXT_NOFAIL /** \endcond */ /** The direction of a pa_stream object */ diff --git a/src/pulse/internal.h b/src/pulse/internal.h index c08bd26a..8c242949 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -42,6 +42,7 @@ #include <pulsecore/hashmap.h> #include <pulsecore/refcnt.h> #include <pulsecore/time-smoother.h> +#include <pulsecore/dbus-util.h> #include "client-conf.h" @@ -50,6 +51,10 @@ struct pa_context { PA_REFCNT_DECLARE; + pa_bool_t no_fail:1; + pa_dbus_wrap_connection *system_bus; + pa_dbus_wrap_connection *session_bus; + pa_proplist *proplist; pa_mainloop_api* mainloop; diff --git a/src/pulsecore/dbus-shared.c b/src/pulsecore/dbus-shared.c new file mode 100644 index 00000000..b52c14cb --- /dev/null +++ b/src/pulsecore/dbus-shared.c @@ -0,0 +1,111 @@ +/*** + This file is part of PulseAudio. + + Copyright 2004-2006, 2009 Lennart Poettering + Copyright 2006 Shams E. King + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdarg.h> + +#include <pulse/xmalloc.h> +#include <pulse/timeval.h> +#include <pulsecore/log.h> +#include <pulsecore/shared.h> + +#include "dbus-shared.h" + +struct pa_dbus_connection { + PA_REFCNT_DECLARE; + + pa_dbus_wrap_connection *connection; + pa_core *core; + const char *property_name; +}; + +static pa_dbus_connection* pa_dbus_connection_new(pa_core *c, pa_dbus_wrap_connection *conn, const char *name) { + pa_dbus_connection *pconn; + + pconn = pa_xnew(pa_dbus_connection, 1); + PA_REFCNT_INIT(pconn); + pconn->core = c; + pconn->property_name = name; + pconn->connection = conn; + + pa_shared_set(c, name, pconn); + + return pconn; +} + +pa_dbus_connection* pa_dbus_bus_get(pa_core *c, DBusBusType type, DBusError *error) { + + static const char *const prop_name[] = { + [DBUS_BUS_SESSION] = "dbus-connection-session", + [DBUS_BUS_SYSTEM] = "dbus-connection-system", + [DBUS_BUS_STARTER] = "dbus-connection-starter" + }; + pa_dbus_wrap_connection *conn; + pa_dbus_connection *pconn; + + pa_assert(type == DBUS_BUS_SYSTEM || type == DBUS_BUS_SESSION || type == DBUS_BUS_STARTER); + + if ((pconn = pa_shared_get(c, prop_name[type]))) + return pa_dbus_connection_ref(pconn); + + if (!(conn = pa_dbus_wrap_connection_new(c->mainloop, type, error))) + return NULL; + + pconn = pa_dbus_connection_new(c, conn, prop_name[type]); + + return pconn; +} + +DBusConnection* pa_dbus_connection_get(pa_dbus_connection *c){ + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) > 0); + pa_assert(c->connection); + + return pa_dbus_wrap_connection_get(c->connection); +} + +void pa_dbus_connection_unref(pa_dbus_connection *c) { + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) > 0); + + if (PA_REFCNT_DEC(c) > 0) + return; + + /* already disconnected, just free */ + pa_shared_remove(c->core, c->property_name); + pa_xfree(c); +} + +pa_dbus_connection* pa_dbus_connection_ref(pa_dbus_connection *c) { + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) > 0); + + PA_REFCNT_INC(c); + + return c; +} + + + diff --git a/src/pulsecore/dbus-shared.h b/src/pulsecore/dbus-shared.h new file mode 100644 index 00000000..4c154552 --- /dev/null +++ b/src/pulsecore/dbus-shared.h @@ -0,0 +1,42 @@ +#ifndef foodbussharedhfoo +#define foodbussharedhfoo + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006, 2009 Lennart Poettering + Copyright 2006 Shams E. King + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include <dbus/dbus.h> + +#include <pulsecore/core.h> +#include <pulsecore/dbus-util.h> + +typedef struct pa_dbus_connection pa_dbus_connection; + +/* return a pa_dbus_connection of the specified type for the given core, + * like dbus_bus_get(), but integrates the connection with the pa_core */ +pa_dbus_connection* pa_dbus_bus_get(pa_core *c, DBusBusType type, DBusError *error); + +DBusConnection* pa_dbus_connection_get(pa_dbus_connection *conn); + +pa_dbus_connection* pa_dbus_connection_ref(pa_dbus_connection *conn); +void pa_dbus_connection_unref(pa_dbus_connection *conn); + +#endif diff --git a/src/modules/dbus-util.c b/src/pulsecore/dbus-util.c index e2d45803..d712bff3 100644 --- a/src/modules/dbus-util.c +++ b/src/pulsecore/dbus-util.c @@ -29,16 +29,12 @@ #include <pulse/xmalloc.h> #include <pulse/timeval.h> #include <pulsecore/log.h> -#include <pulsecore/shared.h> #include "dbus-util.h" -struct pa_dbus_connection { - PA_REFCNT_DECLARE; - - pa_core *core; +struct pa_dbus_wrap_connection { + pa_mainloop_api *mainloop; DBusConnection *connection; - const char *property_name; pa_defer_event* dispatch_event; }; @@ -53,20 +49,20 @@ static void dispatch_cb(pa_mainloop_api *ea, pa_defer_event *ev, void *userdata) /* DBusDispatchStatusFunction callback for the pa mainloop */ static void dispatch_status(DBusConnection *conn, DBusDispatchStatus status, void *userdata) { - pa_dbus_connection *c = userdata; + pa_dbus_wrap_connection *c = userdata; pa_assert(c); switch(status) { case DBUS_DISPATCH_COMPLETE: - c->core->mainloop->defer_enable(c->dispatch_event, 0); + c->mainloop->defer_enable(c->dispatch_event, 0); break; case DBUS_DISPATCH_DATA_REMAINS: case DBUS_DISPATCH_NEED_MEMORY: default: - c->core->mainloop->defer_enable(c->dispatch_event, 1); + c->mainloop->defer_enable(c->dispatch_event, 1); break; } } @@ -135,7 +131,7 @@ static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struc /* DBusAddWatchFunction callback for pa mainloop */ static dbus_bool_t add_watch(DBusWatch *watch, void *data) { - pa_core *c = PA_CORE(data); + pa_dbus_wrap_connection *c = data; pa_io_event *ev; pa_assert(watch); @@ -157,7 +153,7 @@ static dbus_bool_t add_watch(DBusWatch *watch, void *data) { /* DBusRemoveWatchFunction callback for pa mainloop */ static void remove_watch(DBusWatch *watch, void *data) { - pa_core *c = PA_CORE(data); + pa_dbus_wrap_connection *c = data; pa_io_event *ev; pa_assert(watch); @@ -169,11 +165,11 @@ static void remove_watch(DBusWatch *watch, void *data) { /* DBusWatchToggledFunction callback for pa mainloop */ static void toggle_watch(DBusWatch *watch, void *data) { - pa_core *c = PA_CORE(data); + pa_dbus_wrap_connection *c = data; pa_io_event *ev; pa_assert(watch); - pa_core_assert_ref(c); + pa_assert(c); pa_assert_se(ev = dbus_watch_get_data(watch)); @@ -183,7 +179,7 @@ static void toggle_watch(DBusWatch *watch, void *data) { /* DBusAddTimeoutFunction callback for pa mainloop */ static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) { - pa_core *c = PA_CORE(data); + pa_dbus_wrap_connection *c = data; pa_time_event *ev; struct timeval tv; @@ -205,7 +201,7 @@ static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) { /* DBusRemoveTimeoutFunction callback for pa mainloop */ static void remove_timeout(DBusTimeout *timeout, void *data) { - pa_core *c = PA_CORE(data); + pa_dbus_wrap_connection *c = data; pa_time_event *ev; pa_assert(timeout); @@ -217,7 +213,7 @@ static void remove_timeout(DBusTimeout *timeout, void *data) { /* DBusTimeoutToggledFunction callback for pa mainloop */ static void toggle_timeout(DBusTimeout *timeout, void *data) { - pa_core *c = PA_CORE(data); + pa_dbus_wrap_connection *c = data; pa_time_event *ev; pa_assert(timeout); @@ -237,95 +233,59 @@ static void toggle_timeout(DBusTimeout *timeout, void *data) { } static void wakeup_main(void *userdata) { - pa_dbus_connection *c = userdata; + pa_dbus_wrap_connection *c = userdata; pa_assert(c); /* this will wakeup the mainloop and dispatch events, although * it may not be the cleanest way of accomplishing it */ - c->core->mainloop->defer_enable(c->dispatch_event, 1); + c->mainloop->defer_enable(c->dispatch_event, 1); } -static pa_dbus_connection* pa_dbus_connection_new(pa_core* c, DBusConnection *conn, const char* name) { - pa_dbus_connection *pconn; +pa_dbus_wrap_connection* pa_dbus_wrap_connection_new(pa_mainloop_api *m, DBusBusType type, DBusError *error) { + DBusConnection *conn; + pa_dbus_wrap_connection *pconn = NULL; - pconn = pa_xnew(pa_dbus_connection, 1); - PA_REFCNT_INIT(pconn); - pconn->core = c; - pconn->property_name = name; - pconn->connection = conn; - pconn->dispatch_event = c->mainloop->defer_new(c->mainloop, dispatch_cb, conn); + pa_assert(type == DBUS_BUS_SYSTEM || type == DBUS_BUS_SESSION || type == DBUS_BUS_STARTER); - pa_shared_set(c, name, pconn); + if (!(conn = dbus_bus_get_private(type, error))) + return NULL; - return pconn; -} + pconn = pa_xnew(pa_dbus_wrap_connection, 1); + pconn->mainloop = m; + pconn->connection = conn; -DBusConnection* pa_dbus_connection_get(pa_dbus_connection *c){ - pa_assert(c); - pa_assert(PA_REFCNT_VALUE(c) > 0); - pa_assert(c->connection); + dbus_connection_set_exit_on_disconnect(conn, FALSE); + dbus_connection_set_dispatch_status_function(conn, dispatch_status, pconn, NULL); + dbus_connection_set_watch_functions(conn, add_watch, remove_watch, toggle_watch, pconn, NULL); + dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout, toggle_timeout, pconn, NULL); + dbus_connection_set_wakeup_main_function(conn, wakeup_main, pconn, NULL); + + pconn->dispatch_event = pconn->mainloop->defer_new(pconn->mainloop, dispatch_cb, conn); - return c->connection; + return pconn; } -void pa_dbus_connection_unref(pa_dbus_connection *c) { +void pa_dbus_wrap_connection_free(pa_dbus_wrap_connection* c) { pa_assert(c); - pa_assert(PA_REFCNT_VALUE(c) > 0); - - if (PA_REFCNT_DEC(c) > 0) - return; if (dbus_connection_get_is_connected(c->connection)) { dbus_connection_close(c->connection); - /* must process remaining messages, bit of a kludge to handle + /* must process remaining messages, bit of a kludge to handle * both unload and shutdown */ while (dbus_connection_read_write_dispatch(c->connection, -1)); } - /* already disconnected, just free */ - pa_shared_remove(c->core, c->property_name); - c->core->mainloop->defer_free(c->dispatch_event); + c->mainloop->defer_free(c->dispatch_event); dbus_connection_unref(c->connection); pa_xfree(c); } -pa_dbus_connection* pa_dbus_connection_ref(pa_dbus_connection *c) { - pa_assert(c); - pa_assert(PA_REFCNT_VALUE(c) > 0); +DBusConnection* pa_dbus_wrap_connection_get(pa_dbus_wrap_connection *c) { + pa_assert(c); + pa_assert(c->connection); - PA_REFCNT_INC(c); - - return c; -} - -pa_dbus_connection* pa_dbus_bus_get(pa_core *c, DBusBusType type, DBusError *error) { - - static const char *const prop_name[] = { - [DBUS_BUS_SESSION] = "dbus-connection-session", - [DBUS_BUS_SYSTEM] = "dbus-connection-system", - [DBUS_BUS_STARTER] = "dbus-connection-starter" - }; - DBusConnection *conn; - pa_dbus_connection *pconn; - - pa_assert(type == DBUS_BUS_SYSTEM || type == DBUS_BUS_SESSION || type == DBUS_BUS_STARTER); - - if ((pconn = pa_shared_get(c, prop_name[type]))) - return pa_dbus_connection_ref(pconn); - - if (!(conn = dbus_bus_get_private(type, error))) - return NULL; - - pconn = pa_dbus_connection_new(c, conn, prop_name[type]); - - dbus_connection_set_exit_on_disconnect(conn, FALSE); - dbus_connection_set_dispatch_status_function(conn, dispatch_status, pconn, NULL); - dbus_connection_set_watch_functions(conn, add_watch, remove_watch, toggle_watch, c, NULL); - dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout, toggle_timeout, c, NULL); - dbus_connection_set_wakeup_main_function(conn, wakeup_main, pconn, NULL); - - return pconn; + return c->connection; } int pa_dbus_add_matches(DBusConnection *c, DBusError *error, ...) { diff --git a/src/modules/dbus-util.h b/src/pulsecore/dbus-util.h index 554f41a4..55cda7a0 100644 --- a/src/modules/dbus-util.h +++ b/src/pulsecore/dbus-util.h @@ -24,27 +24,22 @@ #include <dbus/dbus.h> -#include <pulsecore/core.h> #include <pulsecore/llist.h> +#include <pulse/mainloop-api.h> -typedef struct pa_dbus_connection pa_dbus_connection; +/* A wrap connection is not shared or refcounted, it is available in client side */ +typedef struct pa_dbus_wrap_connection pa_dbus_wrap_connection; -/* return the DBusConnection of the specified type for the given core, - * like dbus_bus_get(), but integrates the connection with the pa_core */ -pa_dbus_connection* pa_dbus_bus_get(pa_core *c, DBusBusType type, DBusError *error); +pa_dbus_wrap_connection* pa_dbus_wrap_connection_new(pa_mainloop_api *mainloop, DBusBusType type, DBusError *error); +void pa_dbus_wrap_connection_free(pa_dbus_wrap_connection* conn); -DBusConnection* pa_dbus_connection_get(pa_dbus_connection *conn); - -pa_dbus_connection* pa_dbus_connection_ref(pa_dbus_connection *conn); -void pa_dbus_connection_unref(pa_dbus_connection *conn); +DBusConnection* pa_dbus_wrap_connection_get(pa_dbus_wrap_connection *conn); int pa_dbus_add_matches(DBusConnection *c, DBusError *error, ...) PA_GCC_SENTINEL; void pa_dbus_remove_matches(DBusConnection *c, ...) PA_GCC_SENTINEL; typedef struct pa_dbus_pending pa_dbus_pending; -struct userdata; /* We leave the actual definition to the caller */ - struct pa_dbus_pending { DBusConnection *connection; DBusMessage *message; diff --git a/src/tests/gtk-test.c b/src/tests/gtk-test.c index f82aca58..6470e484 100644 --- a/src/tests/gtk-test.c +++ b/src/tests/gtk-test.c @@ -29,12 +29,38 @@ #include <pulse/context.h> #include <pulse/glib-mainloop.h> +pa_context *ctxt; +pa_glib_mainloop *m; + +static void context_state_callback(pa_context *c, void *userdata); + +static void connect(void) { + int r; + + ctxt = pa_context_new(pa_glib_mainloop_get_api(m), NULL); + g_assert(ctxt); + + r = pa_context_connect(ctxt, NULL, PA_CONTEXT_NOAUTOSPAWN|PA_CONTEXT_NOFAIL, NULL); + g_assert(r == 0); + + pa_context_set_state_callback(ctxt, context_state_callback, NULL); +} + +static void context_state_callback(pa_context *c, void *userdata) { + switch (pa_context_get_state(c)) { + case PA_CONTEXT_FAILED: + pa_context_unref(ctxt); + ctxt = NULL; + connect(); + break; + default: + break; + } +} + int main(int argc, char *argv[]) { - pa_context *c; - pa_glib_mainloop *m; GtkWidget *window; - int r; gtk_init(&argc, &argv); @@ -49,15 +75,10 @@ int main(int argc, char *argv[]) { m = pa_glib_mainloop_new(NULL); g_assert(m); - c = pa_context_new(pa_glib_mainloop_get_api(m), NULL); - g_assert(c); - - r = pa_context_connect(c, NULL, 0, NULL); - g_assert(r == 0); - + connect(); gtk_main(); - pa_context_unref(c); + pa_context_unref(ctxt); pa_glib_mainloop_free(m); return 0; |