# Check for PulseAudio.
PKG_CHECK_MODULES(PULSE, libpulse >= 0.9.22)
+PKG_CHECK_MODULES(PULSE_GLIB, libpulse-mainloop-glib >= 0.922)
AC_SUBST(PULSE_CFLAGS)
AC_SUBST(PULSE_LIBS)
+AC_SUBST(PULSE_GLIB_CFLAGS)
+AC_SUBST(PULSE_GLIB_LIBS)
# Check if potentially GPL bits are allowed to be enabled.
AC_ARG_ENABLE(gpl,
# Check for libudev.
PKG_CHECK_MODULES(UDEV, libudev)
+# Check for glib et al that we need temporarily to allow plugins use gdbus.
+PKG_CHECK_MODULES(GLIB, glib-2.0 gobject-2.0)
+PKG_CHECK_MODULES(MURPHY_GLIB, murphy-glib)
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+AC_SUBST(MURPHY_GLIB_CFLAGS)
+AC_SUBST(MURPHY_GLIB_LIBS)
+
# Shave by default.
SHAVE_INIT([build-aux], [enable])
plugin_LTLIBRARIES =
INCLUDES = -I$(top_builddir)
-AM_CFLAGS = $(INCLUDES)
+AM_CFLAGS = $(INCLUDES) $(GLIB_CFLAGS)
QUIET_GEN = $(Q:@=@echo ' GEN '$@;)
$(MURPHY_PULSE_CFLAGS) \
$(MURPHY_COMMON_CFLAGS) \
$(MURPHY_RESOURCE_CFLAGS) \
- $(PULSE_CFLAGS)
+ $(PULSE_CFLAGS) \
+ $(PULSE_GLIB_CFLAGS) \
+ $(MURPHY_GLIB_CFLAGS) \
+ $(GLIB_CFLAGS)
srs_daemon_LDADD = \
$(MURPHY_PULSE_LIBS) \
$(MURPHY_RESOURCE_LIBS) \
$(MURPHY_COMMON_LIBS) \
$(PULSE_LIBS) \
+ $(PULSE_GLIB_LIBS) \
+ $(MURPHY_GLIB_LIBS) \
+ $(GLIB_LIBS) \
-ldl
srs_daemon_LDFLAGS = \
#ifndef __SRS_DAEMON_CONTEXT_H__
#define __SRS_DAEMON_CONTEXT_H__
+#include <pulse/mainloop.h>
+#include <pulse/glib-mainloop.h>
+
#include <murphy/common/list.h>
#include <murphy/common/pulse-glue.h>
#include <murphy/common/hashtbl.h>
+#include <murphy/common/glib-glue.h>
#include <murphy/plugins/resource-native/libmurphy-resource/resource-api.h>
*/
struct srs_context_s {
- pa_mainloop *pa; /* pulseaudio mainloop */
+ GMainLoop *gl; /* GMainLoop if enabled and used */
+ void *pl; /* PA (native or glib) mainloop */
+ pa_mainloop_api *pa; /* PA mainloop API */
mrp_mainloop_t *ml; /* associated murphy mainloop */
mrp_list_hook_t clients; /* connected clients */
mrp_list_hook_t plugins; /* loaded plugins */
#include <murphy/common/log.h>
#include <murphy/common/utils.h>
+#include <glib-object.h>
+
#include "src/daemon/context.h"
#include "src/daemon/config.h"
#include "src/daemon/resourceif.h"
#include "src/daemon/recognizer.h"
+static void cleanup_mainloop(srs_context_t *srs);
+
static void cleanup_context(srs_context_t *srs)
{
if (srs != NULL) {
resource_disconnect(srs);
-
- if (srs->ml != NULL)
- mrp_mainloop_destroy(srs->ml);
-
- if (srs->pa != NULL)
- pa_mainloop_free(srs->pa);
+ cleanup_mainloop(srs);
mrp_free(srs);
}
mrp_list_init(&srs->plugins);
mrp_list_init(&srs->recognizers);
mrp_list_init(&srs->disambiguators);
-
- srs->pa = pa_mainloop_new();
- srs->ml = mrp_mainloop_pulse_get(pa_mainloop_get_api(srs->pa));
-
- if (srs->pa != NULL && srs->ml != NULL)
- if (resource_connect(srs))
- return srs;
-
- cleanup_context(srs);
}
- return NULL;
+ return srs;
}
}
+static void create_mainloop(srs_context_t *srs)
+{
+ if (srs_get_bool_config(srs->settings, "gmainloop", FALSE)) {
+ mrp_log_info("Configured to run with glib mainloop.");
+
+ g_type_init();
+ srs->gl = g_main_loop_new(NULL, FALSE);
+
+ if (srs->gl == NULL) {
+ mrp_log_error("Failed to create GMainLoop.");
+ exit(1);
+ }
+ }
+ else
+ mrp_log_info("Configured to run with native PA mainloop.");
+
+ if (srs->gl == NULL) {
+ srs->pl = pa_mainloop_new();
+ srs->pa = pa_mainloop_get_api(srs->pl);
+ srs->ml = mrp_mainloop_pulse_get(srs->pa);
+ }
+ else {
+ srs->pl = pa_glib_mainloop_new(g_main_loop_get_context(srs->gl));
+ srs->pa = pa_glib_mainloop_get_api(srs->pl);
+ srs->ml = mrp_mainloop_glib_get(srs->gl);
+ }
+
+ if (srs->pa != NULL && srs->ml != NULL)
+ if (resource_connect(srs))
+ return;
+
+ cleanup_context(srs);
+ exit(1);
+}
+
+
static void run_mainloop(srs_context_t *srs)
{
- pa_mainloop_run(srs->pa, &srs->exit_status);
+ if (srs->gl == NULL)
+ pa_mainloop_run((pa_mainloop *)srs->pl, &srs->exit_status);
+ else
+ g_main_loop_run(srs->gl);
}
static void quit_mainloop(srs_context_t *srs, int exit_status)
{
- if (srs != NULL)
- pa_mainloop_quit(srs->pa, exit_status);
+ if (srs != NULL) {
+ if (srs->gl != NULL)
+ g_main_loop_quit(srs->gl);
+ else
+ pa_mainloop_quit((pa_mainloop *)srs->pl, exit_status);
+ }
else
exit(exit_status);
}
+static void cleanup_mainloop(srs_context_t *srs)
+{
+ mrp_mainloop_destroy(srs->ml);
+ srs->ml = NULL;
+
+ if (srs->gl == NULL) {
+ if (srs->pl != NULL)
+ pa_mainloop_free(srs->pl);
+ }
+ else {
+ pa_glib_mainloop_free(srs->pl);
+ g_main_loop_unref(srs->gl);
+ srs->gl = NULL;
+ }
+
+ srs->pl = NULL;
+ srs->pa = NULL;
+}
+
+
static void sighandler(mrp_sighandler_t *h, int signum, void *user_data)
{
static int rlog = FALSE;
if (srs != NULL) {
srs->rlog = mrp_res_set_logger(NULL);
- setup_signals(srs);
config_parse_cmdline(srs, argc, argv);
setup_logging(srs);
+ create_mainloop(srs);
+ setup_signals(srs);
+
if (!srs_configure_plugins(srs)) {
mrp_log_error("Some plugins failed to configure.");
exit(1);
srs_stop_plugins(srs);
srs_destroy_plugins(srs);
+ cleanup_mainloop(srs);
cleanup_context(srs);
exit(0);
srs_plugin_t *plugin = ctx->plugin;
srs_context_t *srs = plugin->srs;
- pa_mainloop_api *mlapi = pa_mainloop_get_api(srs->pa);
+ pa_mainloop_api *mlapi = srs->pa;
char id[512];
size_t idx;
input_t *inp;
{
srs_plugin_t *plugin = ctx->plugin;
srs_context_t *srs = plugin->srs;
- pa_mainloop_api *mlapi = pa_mainloop_get_api(srs->pa);
+ pa_mainloop_api *mlapi = srs->pa;
input_t *inp, *inputs;
size_t i, ninput, size;
uint32_t, void *);
-int pulse_interface_create(context_t *ctx, pa_mainloop *mloop)
+int pulse_interface_create(context_t *ctx, pa_mainloop_api *api)
{
pulse_interface_t *pulseif;
- pa_mainloop_api *api = NULL;
if (!(pulseif = mrp_allocz(sizeof(pulse_interface_t))))
goto failed;
- api = pa_mainloop_get_api(mloop);
-
if (pa_signal_init(api) < 0)
goto failed;
- pulseif->mloop = mloop;
+ pulseif->api = api;
ctx->pulseif = pulseif;
static void connect_to_server(context_t *ctx)
{
pulse_interface_t *pulseif = ctx->pulseif;
- pa_mainloop_api *api = pa_mainloop_get_api(pulseif->mloop);
+ pa_mainloop_api *api = pulseif->api;
pa_context *pactx;
if (pulseif->pactx) {
#include "sphinx-plugin.h"
struct pulse_interface_s {
- pa_mainloop *mloop;
+ pa_mainloop_api *api;
pa_context *pactx;
pa_stream *stream;
bool conup;
bool corked;
};
-int pulse_interface_create(context_t *ctx, pa_mainloop *mloop);
+int pulse_interface_create(context_t *ctx, pa_mainloop_api *api);
void pulse_interface_destroy(context_t *ctx);
void pulse_interface_cork_input_stream(context_t *ctx, bool cork);