summaryrefslogtreecommitdiff
path: root/pulseaudiopatch/genivipulseaudio.patch
diff options
context:
space:
mode:
Diffstat (limited to 'pulseaudiopatch/genivipulseaudio.patch')
-rw-r--r--pulseaudiopatch/genivipulseaudio.patch1749
1 files changed, 1749 insertions, 0 deletions
diff --git a/pulseaudiopatch/genivipulseaudio.patch b/pulseaudiopatch/genivipulseaudio.patch
new file mode 100644
index 0000000..cc7f42d
--- /dev/null
+++ b/pulseaudiopatch/genivipulseaudio.patch
@@ -0,0 +1,1749 @@
+diff -crBN pulseaudio-0.9.22/configure.ac pulseaudio-0.9.22-patched/configure.ac
+*** pulseaudio-0.9.22/configure.ac 2010-11-26 01:45:43.000000000 +0100
+--- pulseaudio-0.9.22-patched/configure.ac 2011-06-30 15:16:20.224520001 +0200
+***************
+*** 1273,1279 ****
+ AC_SUBST(HAVE_OPENSSL)
+ AM_CONDITIONAL([HAVE_OPENSSL], [test "x$HAVE_OPENSSL" = x1])
+
+! ### Build and Install man pages ###
+ AC_ARG_ENABLE(manpages,
+ AS_HELP_STRING([--disable-manpages],[Disable building and installation of man pages]),
+ [case "${enableval}" in
+--- 1273,1300 ----
+ AC_SUBST(HAVE_OPENSSL)
+ AM_CONDITIONAL([HAVE_OPENSSL], [test "x$HAVE_OPENSSL" = x1])
+
+! #### GENIVI support ####
+! AC_ARG_ENABLE([genivi],
+! AC_HELP_STRING([--disable-genivi],[Disable optional genivi module support]),
+! [
+! case "${enableval}" in
+! yes) genivi=yes ;;
+! no) genivi=no ;;
+! *) AC_MSG_ERROR(bad value ${enableval} for --disable-genivi) ;;
+! esac
+! ],
+! [genivi=yes])
+!
+! if test "x${genivi}" != xno && test "x$HAVE_DBUS" = x1; then
+! AC_DEFINE([GENIVI], 1, [Have GENIVI module.])
+! GENIVI=1
+! else
+! GENIVI=0
+! fi
+!
+! AM_CONDITIONAL([GENIVI], [test "x$GENIVI" = x1])
+!
+! ## Build and Install man pages ###
+ AC_ARG_ENABLE(manpages,
+ AS_HELP_STRING([--disable-manpages],[Disable building and installation of man pages]),
+ [case "${enableval}" in
+***************
+*** 1525,1530 ****
+--- 1546,1556 ----
+ ENABLE_PER_USER_ESOUND_SOCKET=yes
+ fi
+
++ ENABLE_GENIVI_SUPPORT=no
++ if test "x$GENIVI" = "x1" ; then
++ ENABLE_GENIVI_SUPPORT=yes
++ fi
++
+ echo "
+ ---{ $PACKAGE_NAME $VERSION }---
+
+***************
+*** 1560,1566 ****
+ Enable tdb: ${ENABLE_TDB}
+ Enable gdbm: ${ENABLE_GDBM}
+ Enable simple database: ${ENABLE_SIMPLEDB}
+!
+ System User: ${PA_SYSTEM_USER}
+ System Group: ${PA_SYSTEM_GROUP}
+ Access Group: ${PA_ACCESS_GROUP}
+--- 1586,1592 ----
+ Enable tdb: ${ENABLE_TDB}
+ Enable gdbm: ${ENABLE_GDBM}
+ Enable simple database: ${ENABLE_SIMPLEDB}
+! Enable Genivi support ${ENABLE_GENIVI_SUPPORT}
+ System User: ${PA_SYSTEM_USER}
+ System Group: ${PA_SYSTEM_GROUP}
+ Access Group: ${PA_ACCESS_GROUP}
+diff -crBN pulseaudio-0.9.22/HOWTO testing pulseaudio-0.9.22-patched/HOWTO testing
+*** pulseaudio-0.9.22/HOWTO testing 1970-01-01 01:00:00.000000000 +0100
+--- pulseaudio-0.9.22-patched/HOWTO testing 2011-06-30 15:16:20.224520001 +0200
+***************
+*** 0 ****
+--- 1,24 ----
++ HOWTO testing
++
++ Created on: Mar 24, 2011
++ Author: blacky
++
++ In order to test the pulseaudio server, this figured the best way to do that:
++
++ first, deinstall pulse audio with apt-get for example
++
++ unpack pulseaudio,
++ add modified modules,
++ patch configure.ac,
++ patch src/Makefile.am
++
++ change src/default.pa
++
++ run /bootstrap
++ run /configure
++
++ to start from commandline with log output, do
++
++ src/pulseaudio -n -F src/default.pa -p $(pwd)/src/.libs/ -vvvv
++
++ in the directory of pulse
+diff -crBN pulseaudio-0.9.22/src/Genivi.conf pulseaudio-0.9.22-patched/src/Genivi.conf
+*** pulseaudio-0.9.22/src/Genivi.conf 1970-01-01 01:00:00.000000000 +0100
+--- pulseaudio-0.9.22-patched/src/Genivi.conf 2011-06-30 15:16:20.224520001 +0200
+***************
+*** 0 ****
+--- 1,12 ----
++ Source:Rhythmbox,default
++ Source:Totem Movie Player,default
++ Source:navigation,nav
++ Source:player,default
++ Source:radio,rad
++ Source:ta,ta
++ Source:rtp,default
++ Sink:tunnel,default
++ Sink:alsa_usb,default
++ Sink:alsa_intern,default
++ Gateway:gw_Pulse_Jack,jack_out,PulseAudio JACK Sink,JACK,gw_out
++ Gateway:gw_Jack_Pulse,PulseAudio JACK Source,jack_in,JACK,gw_in
+diff -crBN pulseaudio-0.9.22/src/Makefile.am pulseaudio-0.9.22-patched/src/Makefile.am
+*** pulseaudio-0.9.22/src/Makefile.am 2010-11-26 01:45:43.000000000 +0100
+--- pulseaudio-0.9.22-patched/src/Makefile.am 2011-06-30 15:16:20.228520001 +0200
+***************
+*** 1576,1581 ****
+--- 1576,1590 ----
+ module_always_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+ module_always_sink_la_CFLAGS = $(AM_CFLAGS)
+
++ # Genivi module
++ if GENIVI
++ modlibexec_LTLIBRARIES += module-genivi.la
++ module_genivi_la_SOURCES = modules/module-genivi.c
++ module_genivi_la_LDFLAGS = $(MODULE_LDFLAGS)
++ module_genivi_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
++ module_genivi_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
++ endif
++
+ # Rescue streams module
+ module_rescue_streams_la_SOURCES = modules/module-rescue-streams.c
+ module_rescue_streams_la_LDFLAGS = $(MODULE_LDFLAGS)
+diff -crBN pulseaudio-0.9.22/src/modules/module-genivi.c pulseaudio-0.9.22-patched/src/modules/module-genivi.c
+*** pulseaudio-0.9.22/src/modules/module-genivi.c 1970-01-01 01:00:00.000000000 +0100
+--- pulseaudio-0.9.22-patched/src/modules/module-genivi.c 2011-06-30 15:16:20.232519999 +0200
+***************
+*** 0 ****
+--- 1,1503 ----
++ /***
++ To be done
++ ***/
++
++
++ #ifdef HAVE_CONFIG_H
++ #include <config.h>
++ #endif
++
++ #include <stdio.h>
++ #include <stdlib.h>
++ #include <string.h>
++ #include <unistd.h>
++
++ #include <pulse/xmalloc.h>
++ #include <pulse/util.h>
++ #include <pulse/i18n.h>
++ #include <pulse/utf8.h>
++
++ #include <pulsecore/sink.h>
++ #include <pulsecore/llist.h>
++ #include <pulsecore/source.h>
++ #include <pulsecore/core-util.h>
++ #include <pulsecore/log.h>
++ #include <pulsecore/modargs.h>
++ #include <pulsecore/dbus-shared.h>
++ #include <pulsecore/endianmacros.h>
++ #include <pulsecore/namereg.h>
++ #include <pulsecore/mime-type.h>
++ #include <pulsecore/strbuf.h>
++ #include <pulsecore/protocol-http.h>
++ #include <pulsecore/parseaddr.h>
++
++ //#include "module-genivi-symdef.h"
++
++ #define ROUTING_INTERFACE_TARGET "com.Genivi.routinginterface"
++ #define ROUTING_REGISTER_PATH "/Hello"
++ #define ROUTING_INTERFACE_NAME "com.genivi.routing"
++ #define R_REGISTER_SOURCE "registerSource"
++ #define R_REGISTER_DOMAIN "registerDomain"
++ #define R_REGISTER_SINK "registerSink"
++ #define R_REGISTER_GATEWAY "registerGateway"
++ #define R_PEEK_DOMAIN "peekDomain"
++
++ PA_MODULE_AUTHOR("Christian Mueller");
++ PA_MODULE_DESCRIPTION(_("Routing the Genivi way"));
++ PA_MODULE_VERSION(PACKAGE_VERSION);
++ PA_MODULE_LOAD_ONCE(TRUE);
++ PA_MODULE_USAGE("Hello");
++
++ #define SERVICE_NAME "org.genivi.pulse"
++ #define OBJECT_ROOT "/org/genivi/pulse"
++ #define OBJECT_PATH "/pulse"
++ #define OBJECT_PULSE "/org/genivi/pulse/pulse"
++
++ #define THIS_DOMAIN "PULSE"
++
++ #define ROOT_INTROSPECT_XML \
++ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
++ "<node>" \
++ "<interface name='org.freedesktop.DBus.Introspectable'>" \
++ "<method name='Introspect'>" \
++ " <arg name='xml_data' type='s' direction='out'/>" \
++ "</method>" \
++ "</interface>" \
++ "<node name='pulse'>" \
++ "</node>" \
++
++ #define PULSE_INTROSPECT_XML \
++ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
++ "<node name='pulse'>" \
++ " <interface name='"SERVICE_NAME"'>" \
++ " <method name='connect'>" \
++ " <arg name='sourceID' type='i' direction='in' />" \
++ " <arg name='sinkID' type='i' direction='in' />" \
++ " <arg name='connectionID' type='i' direction='in' />" \
++ " <arg name='answer' type='i' direction='out'/>" \
++ " </method>" \
++ " <method name='disconnect'>" \
++ " <arg name='connectionID' type='i' direction='in' />" \
++ " <arg name='answer' type='i' direction='out'/>" \
++ " </method>" \
++ " <method name='setSinkVolume'>" \
++ " <arg name='volume' type='i' direction='in' />" \
++ " <arg name='sinkID' type='i' direction='in' />" \
++ " <arg name='answer' type='i' direction='out'/>" \
++ " </method>" \
++ " <method name='setSourceVolume'>" \
++ " <arg name='volume' type='i' direction='in' />" \
++ " <arg name='sourceID' type='i' direction='in' />" \
++ " <arg name='answer' type='i' direction='out'/>" \
++ " </method>" \
++ " <method name='muteSink'>" \
++ " <arg name='sinkID' type='i' direction='in' />" \
++ " <arg name='answer' type='i' direction='out'/>" \
++ " </method>" \
++ " <method name='muteSource'>" \
++ " <arg name='sourceID' type='i' direction='in' />" \
++ " <arg name='answer' type='i' direction='out'/>" \
++ " </method>" \
++ " <method name='unmuteSink'>" \
++ " <arg name='sinkID' type='i' direction='in' />" \
++ " <arg name='answer' type='i' direction='out'/>" \
++ " </method>" \
++ " <method name='unmuteSource'>" \
++ " <arg name='sourceID' type='i' direction='in' />" \
++ " <arg name='answer' type='i' direction='out'/>" \
++ " </method>" \
++ "</interface>" \
++ "<interface name='org.freedesktop.DBus.Introspectable'>" \
++ "<method name='Introspect'>" \
++ " <arg name='xml_data' type='s' direction='out'/>" \
++ "</method>" \
++ "</interface>" \
++ "</node>"
++
++ static const char* const valid_modargs[] = {
++ "file_name",
++ NULL
++ };
++
++ struct genSink {
++ PA_LLIST_FIELDS(struct genSink);
++ char* name;
++ pa_sink* sink;
++ int ID;
++ };
++
++ struct genSource {
++ PA_LLIST_FIELDS(struct genSource);
++ char* name;
++ pa_source* source;
++ pa_sink* linked_sink;
++ int ID;
++ };
++
++ struct genModule {
++ PA_LLIST_FIELDS(struct genModule);
++ struct genSource* source;
++ struct genSink* sinks;
++ };
++
++ struct genGateways {
++ PA_LLIST_FIELDS(struct genGateways);
++ char* source;
++ char* sinks;
++ int sinkID;
++ int sourceID;
++ int ID;
++ };
++
++ struct genConnections {
++ PA_LLIST_FIELDS(struct genConnections);
++ int ID;
++ struct genSink* Sink;
++ struct genSource* Source;
++ };
++
++ typedef enum {
++ gw_in=0,
++ gw_out
++ }gwDirection_t;
++
++ struct clientGateWays {
++ PA_LLIST_FIELDS(struct clientGateWays);
++ char name[30];
++ char sink_name[30];
++ char source_name[30];
++ char domain_name[30];
++ gwDirection_t direction;
++ };
++
++ struct clientSource {
++ PA_LLIST_FIELDS(struct clientSource);
++ char name[30];
++ char Audioclass[30];
++ };
++
++ struct clientSink {
++ PA_LLIST_FIELDS(struct clientSink);
++ char name[30];
++ char Audioclass[30];
++ };
++
++ struct userdata {
++ char* name;
++ pa_dbus_connection *bus;
++ pa_core *core;
++ PA_LLIST_HEAD(struct genSink, listSinks);
++ PA_LLIST_HEAD(struct genSource, listSources);
++ PA_LLIST_HEAD(struct genModule, listModules);
++ PA_LLIST_HEAD(struct genGateways, listGateways);
++ PA_LLIST_HEAD(struct genConnections, listConnections);
++ PA_LLIST_HEAD(struct clientSink, listClientSinks);
++ PA_LLIST_HEAD(struct clientSource, listClientSources);
++ PA_LLIST_HEAD(struct clientGateWays, listCLientGateways);
++ };
++
++ //<node>
++ // <interface name="com.genivi.routing">
++ // <method name="registerSource">
++ // <arg name="name" type="s" direction="in" />
++ // <arg name="audioclass" type="s" direction="in" />
++ // <arg name="domain" type="s" direction="in"/>
++ // <arg name="assigned_adress" type="i" direction="out"/>
++ // </method>
++ // <method name="registerDomain">
++ // <arg name="name" type="s" direction="in" />
++ // <arg name="node" type="s" direction="in" />
++ // <arg name="earlymode" type="b" direction="in"/>
++ // <arg name="assigned_adress" type="i" direction="out"/>
++ // </method>
++ // <method name="registerSink">
++ // <arg name="name" type="s" direction="in" />
++ // <arg name="sinkclass" type="s" direction="in" />
++ // <arg name="domain" type="s" direction="in"/>
++ // <arg name="assigned_adress" type="i" direction="out"/>
++ // </method>
++ // <method name="registerGateway">
++ // <arg name="name" type=s->name;"s" direction="in" />
++ // <arg name="sink" type="s" direction="in" />
++ // <arg name="source" type="s" direction="in" />
++ // <arg name="domainSource" type="s" direction="in"/>
++ // <arg name="domainSink" type="s" direction="in"/>
++ // <arg name="controlDomain" type="s" direction="in"/>loadConfigFile
++ // <arg name="assigned_adress" type="i" direction="out"/>int RegisterSource(const char* name,const char* audioclass, const char* Domain, void* userdata);
++ // </method>
++ // <signal name="SystemReady"/>
++ //</node>
++
++ //all these functions can be called @ the routinginterface
++ int registerSource(const char* name,const char* audioclass, const char* domain, void* userdata);
++ int registerDomain(const char* name,const char* node, pa_bool_t earlymode, void* userdata);
++ int registerSink(const char* name, const char* sinkclass, const char* domain, void* userdata);
++ int registerGateway(const char* name, const char* sink, const char* source, const char* domainSource, const char* domainSink, const char* controlDomain, void* userdata);
++ int peekDomain(const char* name, void* userdata);
++
++ //all these functions can be called from the routinginterface
++ void DbusHandleConnect(pa_core* c,DBusMessage *m, void* userdata);
++ void DbusHandleDisconnect(pa_core* c,DBusMessage *m, void* userdata);
++ void DbusHandleSetSourceVolume(pa_core* c,DBusMessage *m, void* userdata);
++ void DbusHandleSetSinkVolume(pa_core* c,DBusMessage *m, void* userdata);
++ void DbusHandleMuteSource(pa_core* c,DBusMessage *m, void* userdata);
++ void DbusHandleMuteSink(pa_core* c,DBusMessage *m, void* userdata);
++ void DbusHandleUmuteSource(pa_core* c,DBusMessage *m, void* userdata);
++ void DbusHandleUmuteSink(pa_core* c,DBusMessage *m, void* userdata);
++
++ void intialRegistration(pa_core* c,void* userdata);
++
++ /** This function loads a configuration file with sources and sinks into
++ * the structures.
++ * @param filename the filename. Must be given absolute.
++ */
++ void loadConfigFile(const char* filename,void* userdata);
++
++ int registerSource(const char* name,const char* audioclass, const char* domain, void* userdata) {
++ struct userdata *u = userdata;
++
++ DBusConnection* conn=pa_dbus_connection_get(u->bus);
++ DBusMessage* msg;
++ DBusMessageIter args;
++ DBusPendingCall* pending;
++ int retval;
++
++ pa_assert_se(msg = dbus_message_new_method_call(
++ ROUTING_INTERFACE_TARGET, // target for the method call
++ ROUTING_REGISTER_PATH, // path to call on
++ ROUTING_INTERFACE_NAME, // interface to call on
++ R_REGISTER_SOURCE)); // method name
++
++ if (NULL == msg) {
++ pa_log("Message Null");
++ exit(1);
++ }
++
++ // append arguments
++ pa_assert_se(dbus_message_append_args ( msg,
++ DBUS_TYPE_STRING, &name,
++ DBUS_TYPE_STRING, &audioclass,
++ DBUS_TYPE_STRING, &domain,
++ DBUS_TYPE_INVALID));
++ // send message and get a handle for a reply
++ if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
++ pa_log( "Out Of Memory!\n");
++ exit(1);
++ }
++ if (NULL == pending) {
++ pa_log("Pending Call Null\n");
++ exit(1);
++ }
++ //force message out, if queue did not react
++ dbus_connection_flush(conn);
++
++ pa_log("Send out RegisterSource");
++
++ // free message
++ dbus_message_unref(msg);
++
++ // block until we recieve a reply
++ dbus_pending_call_block(pending);
++
++ // get the reply message
++ msg = dbus_pending_call_steal_reply(pending);
++ if (NULL == msg) {
++ pa_log("Reply Null\n");
++ exit(1);
++ }
++ // free the pending message handle
++ dbus_pending_call_unref(pending);
++
++ // read the parameters
++ if (!dbus_message_iter_init(msg, &args))
++ pa_log("Message has no arguments!\n");
++ else
++ dbus_message_iter_get_basic(&args, &retval);
++
++ pa_log("Got Reply: %i\n", retval);
++
++ // free reply and close connection
++ dbus_message_unref(msg);
++ return retval;
++ }
++
++ int registerDomain(const char* name,const char* node, pa_bool_t earlymode, void* userdata) {
++ struct userdata *u = userdata;
++
++ DBusConnection* conn=pa_dbus_connection_get(u->bus);
++ DBusMessage* msg;
++ DBusMessageIter args;
++ DBusPendingCall* pending;
++ int retval, ibool=0;
++
++ if (earlymode==TRUE) {
++ ibool=1;
++ }
++
++ pa_assert_se(msg = dbus_message_new_method_call(
++ ROUTING_INTERFACE_TARGET, // target for the method call
++ ROUTING_REGISTER_PATH, // path to call on
++ ROUTING_INTERFACE_NAME, // interface to call on
++ R_REGISTER_DOMAIN)); // method name
++
++ if (NULL == msg) {
++ pa_log("Message Null");
++ exit(1);
++ }
++
++ // append arguments
++ pa_assert_se(dbus_message_append_args ( msg,
++ DBUS_TYPE_STRING, &name,
++ DBUS_TYPE_STRING, &node,
++ DBUS_TYPE_BOOLEAN, &ibool,
++ DBUS_TYPE_INVALID));
++
++ pa_log("send message\n");
++ // send message and get a handle for a reply
++ if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
++ pa_log( "Out Of Memory!\n");
++ exit(1);
++ }
++ if (NULL == pending) {
++ pa_log("Pending Call Null\n");
++ exit(1);
++ }
++ //force message out, if queue did not react
++ dbus_connection_flush(conn);
++
++ pa_log("Send out %s",R_REGISTER_DOMAIN);
++
++ // free message
++ dbus_message_unref(msg);
++
++ // block until we recieve a reply
++ dbus_pending_call_block(pending);
++
++ // get the reply message
++ msg = dbus_pending_call_steal_reply(pending);
++ if (NULL == msg) {
++ pa_log("Reply Null\n");
++ exit(1);
++ }
++ // free the pending message handle
++ dbus_pending_call_unref(pending);
++
++ // read the parameters
++ if (!dbus_message_iter_init(msg, &args))
++ pa_log("Message has no arguments!\n");
++ else
++ dbus_message_iter_get_basic(&args, &retval);
++ pa_log("Got Reply: %i\n", retval);
++
++ // free reply and close connection
++ dbus_message_unref(msg);
++ return retval;
++ }
++ int registerSink(const char* name, const char* sinkclass, const char* domain, void* userdata) {
++ struct userdata *u = userdata;
++
++ DBusConnection* conn=pa_dbus_connection_get(u->bus);
++ DBusMessage* msg;
++ DBusMessageIter args;
++ DBusPendingCall* pending;
++ int retval=0;
++
++ pa_assert_se(msg = dbus_message_new_method_call(
++ ROUTING_INTERFACE_TARGET, // target for the method call
++ ROUTING_REGISTER_PATH, // path to call on
++ ROUTING_INTERFACE_NAME, // interface to call on
++ R_REGISTER_SINK)); // method name
++
++ if (NULL == msg) {
++ pa_log("Message Null");
++ exit(1);
++ }
++ pa_log("Sink %s",name);
++ // append arguments
++ pa_assert_se(dbus_message_append_args ( msg,
++ DBUS_TYPE_STRING, &name,
++ DBUS_TYPE_STRING, &sinkclass,
++ DBUS_TYPE_STRING, &domain,
++ DBUS_TYPE_INVALID));
++
++ pa_log("send message\n");
++ // send message and get a handle for a reply
++ if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
++ pa_log( "Out Of Memory!\n");
++ exit(1);
++ }
++ if (NULL == pending) {
++ pa_log("Pending Call Null\n");
++ exit(1);
++ }
++ //force message out, if queue did not react
++ dbus_connection_flush(conn);
++
++ pa_log("Send out %s",R_REGISTER_SINK);
++
++ // free message
++ dbus_message_unref(msg);
++
++ // block until we recieve a reply
++ dbus_pending_call_block(pending);
++
++ // get the reply message
++ msg = dbus_pending_call_steal_reply(pending);
++ if (NULL == msg) {
++ pa_log("Reply Null\n");
++ exit(1);
++ }
++ // free the pending message handle
++ dbus_pending_call_unref(pending);
++
++ // read the parameters
++ if (!dbus_message_iter_init(msg, &args))
++ pa_log("Message has no arguments!\n");
++ else
++ dbus_message_iter_get_basic(&args, &retval);
++
++ pa_log("Got Reply: %i\n", retval);
++
++ // free reply and close connection
++ dbus_message_unref(msg);
++ return retval;
++ }
++ int registerGateway(const char* name, const char* sink, const char* source, const char* domainSource, const char* domainSink, const char* controlDomain, void* userdata) {
++ struct userdata *u = userdata;
++
++ DBusConnection* conn=pa_dbus_connection_get(u->bus);
++ DBusMessage* msg;
++ DBusMessageIter args;
++ DBusPendingCall* pending;
++ int retval=0;
++
++ pa_assert_se(msg = dbus_message_new_method_call(
++ ROUTING_INTERFACE_TARGET, // target for the method call
++ ROUTING_REGISTER_PATH, // path to call on
++ ROUTING_INTERFACE_NAME, // interface to call on
++ R_REGISTER_GATEWAY)); // method name
++
++ if (NULL == msg) {
++ pa_log("Message Null");
++ exit(1);
++ }
++
++ // append arguments
++ pa_assert_se(dbus_message_append_args ( msg,
++ DBUS_TYPE_STRING, &name,
++ DBUS_TYPE_STRING, &sink,
++ DBUS_TYPE_STRING, &source,
++ DBUS_TYPE_STRING, &domainSource,
++ DBUS_TYPE_STRING, &domainSink,
++ DBUS_TYPE_STRING, &controlDomain,
++ DBUS_TYPE_INVALID));
++
++ // send message and get a handle for a reply
++ if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
++ pa_log( "Out Of Memory!\n");
++ exit(1);
++ }
++ if (NULL == pending) {
++ pa_log("Pending Call Null\n");
++ exit(1);
++ }
++ //force message out, if queue did not react
++ dbus_connection_flush(conn);
++
++ pa_log("Send out %s",R_REGISTER_GATEWAY);
++
++ // free message
++ dbus_message_unref(msg);
++
++ // block until we recieve a reply
++ dbus_pending_call_block(pending);
++
++ // get the reply message
++ msg = dbus_pending_call_steal_reply(pending);
++ if (NULL == msg) {
++ pa_log("Reply Null\n");
++ exit(1);
++ }
++ // free the pending message handle
++ dbus_pending_call_unref(pending);
++
++ // read the parameters
++ if (!dbus_message_iter_init(msg, &args))
++ pa_log("Message has no arguments!\n");
++ else
++ dbus_message_iter_get_basic(&args, &retval);
++
++ pa_log("Got Reply: %i\n", retval);
++
++ // free reply and close connection
++ dbus_message_unref(msg);
++ return retval;
++ }
++ int peekDomain(const char* name, void* userdata) {
++ struct userdata *u = userdata;
++
++ DBusConnection* conn=pa_dbus_connection_get(u->bus);
++ DBusMessage* msg;
++ DBusMessageIter args;
++ DBusPendingCall* pending;
++ int retval=0;
++
++ pa_assert_se(msg = dbus_message_new_method_call(
++ ROUTING_INTERFACE_TARGET, // target for the method call
++ ROUTING_REGISTER_PATH, // path to call on
++ ROUTING_INTERFACE_NAME, // interface to call on
++ R_PEEK_DOMAIN)); // method name
++
++ if (NULL == msg) {
++ pa_log("Message Null");
++ exit(1);
++ }
++
++ // append arguments
++ pa_assert_se(dbus_message_append_args ( msg,
++ DBUS_TYPE_STRING, &name,
++ DBUS_TYPE_INVALID));
++
++ // send message and get a handle for a reply
++ if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
++ pa_log( "Out Of Memory!\n");
++ exit(1);
++ }
++ if (NULL == pending) {
++ pa_log("Pending Call Null\n");
++ exit(1);
++ }
++ //force message out, if queue did not react
++ dbus_connection_flush(conn);
++
++ pa_log("Send out %s",R_PEEK_DOMAIN);
++
++ // free message
++ dbus_message_unref(msg);
++
++ // block until we recieve a reply
++ dbus_pending_call_block(pending);
++
++ // get the reply message
++ msg = dbus_pending_call_steal_reply(pending);
++ if (NULL == msg) {
++ pa_log("Reply Null\n");
++ exit(1);
++ }
++ // free the pending message handle
++ dbus_pending_call_unref(pending);
++
++ // read the parameters
++ if (!dbus_message_iter_init(msg, &args))
++ pa_log("Message has no arguments!\n");
++ else
++ dbus_message_iter_get_basic(&args, &retval);
++
++ pa_log("Got Reply: %i\n", retval);
++
++ // free reply and close connection
++ dbus_message_unref(msg);
++ return retval;
++ }
++
++ void DbusHandleConnect(pa_core* c,DBusMessage *m, void* userdata) {
++ struct userdata *u = userdata;
++ DBusMessage *r = NULL;
++ DBusMessageIter args;
++ int connect_source = 0;
++ int connect_sink = 0;
++ int32_t connect_ID;
++
++ if (!dbus_message_iter_init(m, &args)) {
++ pa_log("connect message had no args");
++ }
++ dbus_message_iter_get_basic(&args, &connect_source);
++ dbus_message_iter_next(&args);
++ dbus_message_iter_get_basic(&args, &connect_sink);
++ dbus_message_iter_next(&args);
++ dbus_message_iter_get_basic(&args, &connect_ID);
++ pa_log("Connect was called. Shall connect %d to %d, conn ID %d",connect_source,connect_sink,connect_ID);
++
++ struct genSink* Sink=NULL;
++ PA_LLIST_FOREACH(Sink,u->listSinks) {
++ pa_log("Sink name %s, sink ID %d",Sink->name,Sink->ID);
++ if (Sink->ID==connect_sink) {
++ pa_log("found matching sink : %s!",Sink->name);
++ break;
++ }
++ }
++
++ //for this Sink, there shall be a new Source Linked
++ struct genSource* Source=NULL;
++ PA_LLIST_FOREACH(Source,u->listSources) {
++ if (Source->ID==connect_source) {
++ pa_log("found matching source : %s!",Source->name);
++ Source->linked_sink=Sink->sink;
++ break;
++ }
++ }
++ //ok Sink input for this client exists -> move it !!!!
++ pa_sink_input* s;
++ uint32_t idx, idx2, idx3;
++ PA_IDXSET_FOREACH(s, u->core->sink_inputs, idx) {
++ char* app_name=pa_proplist_gets(s->proplist,PA_PROP_APPLICATION_NAME);
++ if (app_name) {
++ if (strcmp(app_name,Source->name)==0) {
++ pa_log("move it!!!!!!");
++ pa_sink_input_move_to(s,Sink->sink,TRUE);
++ }
++ }
++ }
++
++ pa_source* so;
++ pa_source_output* so_out;
++ PA_IDXSET_FOREACH(so, u->core->sources, idx) {
++ char* name=so->name;
++ if (strcmp(name,Source->name)==0) {
++ pa_log("found to be a real source, taking module-loop %s",Sink->sink->name);
++ PA_IDXSET_FOREACH(s, u->core->sink_inputs, idx2) {
++ char* client=s->module->name;
++ if (strcmp(client,"module-loopback")==0) {
++ pa_log("want to move to %s",Sink->sink->name);
++ pa_sink_input_move_to(s,Sink->sink,TRUE);
++ }
++ }
++ PA_IDXSET_FOREACH(so_out, u->core->source_outputs, idx3) {
++ char* client=so_out->module->name;
++ if (strcmp(client,"module-loopback")==0) {
++ pa_source_output_move_to(so_out,so,TRUE);
++ }
++ }
++ }
++ }
++
++ struct genConnections* gConnect=NULL;
++ gConnect= pa_xnew0(struct genConnections, 1);
++ gConnect->ID=connect_ID;
++ gConnect->Sink=Sink;
++ gConnect->Source=Source;
++ PA_LLIST_PREPEND(struct genConnections,u->listConnections,gConnect);
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ dbus_message_append_args( r,
++ DBUS_TYPE_INT32, &connect_ID,
++ DBUS_TYPE_INVALID);
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++
++ }
++
++ void DBusHandleDisconnect(pa_core* c,DBusMessage *m, void* userdata) {
++ struct userdata *u = userdata;
++ DBusMessage *r = NULL;
++ DBusMessageIter args;
++ int32_t connectID = 0;
++
++ if (!dbus_message_iter_init(m, &args)) {
++ pa_log("disconnect message had no args");
++ }
++ dbus_message_iter_get_basic(&args, &connectID);
++ pa_log("Disconnect was called. Shall disconnect ID %d ",connectID);
++
++ struct genConnections* Connect=NULL;
++ PA_LLIST_FOREACH(Connect,u->listConnections) {
++ if (Connect->ID==connectID) {
++ pa_log("found connection!");
++ break;
++ }
++ }
++
++ Connect->Source->linked_sink=NULL;
++ //pa_sink_detach(Connect->Sink->sink);
++ pa_sink_input* s;
++ uint32_t idx=0,idx2=0;
++ PA_IDXSET_FOREACH(s, Connect->Sink->sink->inputs, idx) {
++ char* app_name=s->sink->name;
++ pa_log("name %s %s",app_name,Connect->Sink->name);
++ if (strcmp(app_name,Connect->Sink->name)==0) {
++ char* module_name=s->module->name;
++ pa_log("module name %s",module_name);
++ if(module_name && strcmp(module_name,"module-loopback")==0) {
++ pa_sink* nu;
++ PA_IDXSET_FOREACH(nu, u->core->sinks, idx2) {
++ char* name=nu->name;
++ if (strcmp(name,"null")==0) {
++ pa_sink_input_move_to(s,nu,TRUE);
++ break;
++ }
++ }
++ } else {
++
++ char* app_name=pa_proplist_gets(s->proplist,PA_PROP_APPLICATION_NAME);
++ if (strcmp(app_name,Connect->Source->name)==0) {
++ pa_sink_input_kill(s);
++ }
++ }
++ }
++ }
++ PA_LLIST_REMOVE(struct genConnections, u->listConnections,Connect);
++
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ dbus_message_append_args( r,
++ DBUS_TYPE_INT32, &connectID,
++ DBUS_TYPE_INVALID);
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++
++ //TODO handle errors
++
++ }
++
++ void DbusHandleSetSourceVolume(pa_core* c,DBusMessage *m, void* userdata) {
++ struct userdata *u = userdata;
++ DBusMessage *r = NULL;
++ DBusMessageIter args;
++ int volume = 0, sourceID=0;
++ int32_t vol32;
++
++ if (!dbus_message_iter_init(m, &args)) {
++ pa_log("SourceVolume message had no args");
++ }
++ dbus_message_iter_get_basic(&args, &volume);
++ dbus_message_iter_next(&args);
++ dbus_message_iter_get_basic(&args, &sourceID);
++ pa_log("SourceVolume was called shall set %d to %d ",sourceID, volume);
++
++ struct genSource* Source=NULL;
++ PA_LLIST_FOREACH(Source,u->listSources) {
++ if (Source->ID==sourceID) {
++ pa_log("found matching source : %s!",Source->name);
++ break;
++ }
++ }
++ pa_cvolume cvol;
++ pa_cvolume_set(&cvol, 1, volume);
++ pa_sink_input* si;
++ int idx=0;
++ PA_IDXSET_FOREACH(si, Source->linked_sink->inputs, idx) {
++ char* app_name=pa_proplist_gets(si->proplist,PA_PROP_APPLICATION_NAME);
++ if (strcmp(app_name,Source->name)==0) {
++ pa_sink_input_set_volume(si, &cvol, TRUE, TRUE);
++ }
++ }
++
++
++ vol32=(int32_t)volume;
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ dbus_message_append_args( r,
++ DBUS_TYPE_INT32, &vol32,
++ DBUS_TYPE_INVALID);
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++ }
++
++ void DbusHandleSetSinkVolume(pa_core* c,DBusMessage *m, void* userdata) {
++ struct userdata *u = userdata;
++ DBusMessage *r = NULL;
++ DBusMessageIter args;
++ int volume = 0, sinkID=0;
++ int32_t vol32;
++
++ if (!dbus_message_iter_init(m, &args)) {
++ pa_log("SinkVolume message had no args");
++ }
++ dbus_message_iter_get_basic(&args, &volume);
++ dbus_message_iter_next(&args);
++ dbus_message_iter_get_basic(&args, &sinkID);
++ pa_log("SinkVolume was called shall set %d to %d ",sinkID, volume);
++
++ struct genSink* Sink=NULL;
++ PA_LLIST_FOREACH(Sink,u->listSinks) {
++ if (Sink->ID==sinkID) {
++ pa_log("found matching source : %s!",Sink->name);
++ break;
++ }
++ }
++ pa_cvolume cvol=Sink->sink->real_volume;
++
++
++ for (int i=0;i<=cvol.channels;i++) {
++ cvol.values[i]=(pa_volume_t)volume;
++ }
++
++ pa_sink_set_volume(Sink->sink,&cvol,TRUE,TRUE);
++
++ vol32=(int32_t) volume;
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ dbus_message_append_args( r,
++ DBUS_TYPE_INT32, &vol32,
++ DBUS_TYPE_INVALID);
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++ }
++
++ void DbusHandleMuteSource(pa_core* c,DBusMessage *m, void* userdata) {
++ struct userdata *u = userdata;
++ DBusMessage *r = NULL;
++ DBusMessageIter args;
++ int SourceID=0;
++ int32_t vol32;
++
++ if (!dbus_message_iter_init(m, &args)) {
++ pa_log("MuteSource message had no args");
++ }
++ dbus_message_iter_get_basic(&args, &SourceID);
++ pa_log("MuteSource was called shall mute %d ",SourceID);
++
++ struct genSource* Source=NULL;
++ PA_LLIST_FOREACH(Source,u->listSources) {
++ if (Source->ID==SourceID) {
++ pa_log("found matching source : %s!",Source->name);
++ break;
++ }
++ }
++
++ pa_sink_input* si;
++ int idx=0;
++ PA_IDXSET_FOREACH(si, Source->linked_sink->inputs, idx) {
++ char* app_name=pa_proplist_gets(si->proplist,PA_PROP_APPLICATION_NAME);
++ if (strcmp(app_name,Source->name)==0) {
++ pa_sink_input_set_mute(si,TRUE,TRUE);
++ }
++ }
++
++ vol32=(int32_t) 1;
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ dbus_message_append_args( r,
++ DBUS_TYPE_INT32, &vol32,
++ DBUS_TYPE_INVALID);
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++ }
++
++ void DbusHandleMuteSink(pa_core* c,DBusMessage *m, void* userdata) {
++ struct userdata *u = userdata;
++ DBusMessage *r = NULL;
++ DBusMessageIter args;
++ int SinkID=0;
++ int32_t vol32;
++
++ if (!dbus_message_iter_init(m, &args)) {
++ pa_log("MuteSource message had no args");
++ }
++ dbus_message_iter_get_basic(&args, &SinkID);
++ pa_log("MuteSink was called shall mute %d ",SinkID);
++
++ struct genSink* Sink=NULL;
++ PA_LLIST_FOREACH(Sink,u->listSinks) {
++ if (Sink->ID==SinkID) {
++ pa_log("found matching source : %s!",Sink->name);
++ break;
++ }
++ }
++
++ pa_sink_set_mute(Sink->sink,TRUE,TRUE);
++
++ vol32=(int32_t) 1;
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ dbus_message_append_args( r,
++ DBUS_TYPE_INT32, &vol32,
++ DBUS_TYPE_INVALID);
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++ }
++
++ void DbusHandleUmuteSource(pa_core* c,DBusMessage *m, void* userdata) {
++ struct userdata *u = userdata;
++ DBusMessage *r = NULL;
++ DBusMessageIter args;
++ int SourceID=0;
++ int32_t vol32;
++
++ if (!dbus_message_iter_init(m, &args)) {
++ pa_log("MuteSource message had no args");
++ }
++ dbus_message_iter_get_basic(&args, &SourceID);
++ pa_log("MuteSource was called shall mute %d ",SourceID);
++
++ struct genSource* Source=NULL;
++ PA_LLIST_FOREACH(Source,u->listSources) {
++ if (Source->ID==SourceID) {
++ pa_log("found matching source : %s!",Source->name);
++ break;
++ }
++ }
++
++ pa_sink_input* si;
++ int idx=0;
++ PA_IDXSET_FOREACH(si, Source->linked_sink->inputs, idx) {
++ char* app_name=pa_proplist_gets(si->proplist,PA_PROP_APPLICATION_NAME);
++ if (strcmp(app_name,Source->name)==0) {
++ pa_sink_input_set_mute(si,FALSE,TRUE);
++ }
++ }
++
++ vol32=(int32_t) 1;
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ dbus_message_append_args( r,
++ DBUS_TYPE_INT32, &vol32,
++ DBUS_TYPE_INVALID);
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++ }
++
++ void DbusHandleUmuteSink(pa_core* c,DBusMessage *m, void* userdata) {
++ struct userdata *u = userdata;
++ DBusMessage *r = NULL;
++ DBusMessageIter args;
++ int SinkID=0;
++ int32_t vol32;
++
++ if (!dbus_message_iter_init(m, &args)) {
++ pa_log("MuteSource message had no args");
++ }
++ dbus_message_iter_get_basic(&args, &SinkID);
++ pa_log("MuteSink was called shall mute %d ",SinkID);
++
++ struct genSink* Sink=NULL;
++ PA_LLIST_FOREACH(Sink,u->listSinks) {
++ if (Sink->ID==SinkID) {
++ pa_log("found matching source : %s!",Sink->name);
++ break;
++ }
++ }
++
++ pa_sink_set_mute(Sink->sink,FALSE,TRUE);
++
++ vol32=(int32_t) 1;
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ dbus_message_append_args( r,
++ DBUS_TYPE_INT32, &vol32,
++ DBUS_TYPE_INVALID);
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++
++ }
++
++ void intialRegistration(pa_core* c,void* userdata) {
++ struct userdata *u = userdata;
++ //first we register the Domain
++ const char * name=THIS_DOMAIN;
++ const char * node="pulsePlugin";
++ pa_bool_t earlymode=FALSE;
++ int k=registerDomain(name,node,earlymode,u);
++
++ pa_sink* s;
++ uint32_t idx_=0;
++ //this is not neccessary -> just nicer names...
++ PA_IDXSET_FOREACH(s, u->core->sinks, idx_) {
++ if (strcmp(s->name,"alsa_output.usb-0ccd_USB_Audio-00-Aureon51MkII.analog-stereo")==0) {
++ strcpy(s->name,"alsa_usb");
++ }
++ if (strcmp(s->name,"alsa_output.default")==0) {
++ strcpy(s->name,"alsa_intern");
++ }
++ }
++
++ //get all current sinks and register them
++ // pa_sink* s;
++ // uint32_t idx;
++ // int handle=0;
++ // pa_bool_t is_gw=FALSE;
++ // PA_IDXSET_FOREACH(s, u->core->sinks, idx) {
++ // is_gw=FALSE;
++ // for (int i=0;i <= sizeof(gatewayList)/sizeof(gateWays_t)-1;i++) {
++ // if (strcmp(s->name,gatewayList[i].sink_name)==0) {
++ // handle=registerGateway(gatewayList[i].name,gatewayList[i].sink_name,gatewayList[i].source_name,gatewayList[i].domain_name,THIS_DOMAIN,THIS_DOMAIN,u);
++ // if (handle>0) {
++ // is_gw=TRUE;
++ //
++ // struct genGateways* gWay=NULL;
++ // gWay= pa_xnew0(struct genGateways, 1);
++ //
++ // struct genSink* Sink=NULL;
++ // Sink = pa_xnew0(struct genSink, 1);
++ //
++ // Sink->sink=NULL;
++ // gWay->ID=handle;
++ //
++ // handle=0;
++ // handle=registerSink(gatewayList[i].sink_name,"default",THIS_DOMAIN,u);
++ // if (handle>0){
++ // Sink->sink=s;
++ // Sink->ID=handle;
++ // Sink->name=s->name;
++ //
++ // gWay->sinks=s->name;
++ // gWay->sinkID=handle;
++ // gWay->source=gatewayList[i].source_name;
++ // gWay->sourceIis_gw=FALSE;D=registerSource(gatewayList[i].source_name,"default",gatewayList[i].domain_name,u);
++ //
++ //
++ // PA_LLIST_PREPEND(struct genGateways,u->listGateways,gWay);
++ // PA_LLIST_PREPEND(struct genSink,u->listSinks,Sink);
++ // } else {
++ // pa_log("Sink register failed");
++ // break;
++ // }
++ // } else {
++ // pa_log("GW register failed");
++ // }
++ // }
++ // }
++ // if ((strcmp(s->name,"null") ==0) && !is_gw) {
++ // pa_log ("found null sink"); //do nothing, no worth it
++ // } else if (!is_gw){
++ // handle=0;
++ // handle=registerSink(s->name,"default",THIS_DOMAIN,u);
++ // if (handle>0) {
++ //
++ // struct genSink* Sit[i].name) {nk=NULL;
++ //
++ // Sink = pa_xnew0(struct genSink, 1);
++ // Sink->sink=NULL;
++ // Sink->sink=s;
++ // Sink->ID=handle;
++ // Sink->name= pa_sink* s;
++ // PA_LLIST_PREPEND(struct genSink,u->listSinks,Sink);
++ // } else {
++ // pa_log("Sink register failed");
++ // }
++ // }
++ // }
++ //
++ // pa_source* so;
++ // handle=0;
++ // //get all current sources and register them
++ // PA_IDXSET_FOREACH(so, u->core->sources, idx) {
++ // pa_log("Source %s",so->name);
++ // is_gw=FALSE;
++ // for (int i=0;i <= sizeof(gatewayList)/sizeof(gateWays_t)-1;i++) {
++ // if (strcmp(so->name,gatewayList[i].source_name)==0) {
++ // handle=registerGateway(gatewayList[i].name,gatewayList[i].sink_name,gatewayList[i].source_name,THIS_DOMAIN,gatewayList[i].domain_name,THIS_DOMAIN,u);
++ // if (handle>0) {
++ // is_gw=TRUE;
++ //
++ // struct genGateways* gWay=NULL;
++ // gWay= pa_xnew0(struct genGateways, 1);
++ //
++ // struct genSource* Source=NULL;
++ // Source= pa_xnew(struct genSource, 1);
++ //
++ // Source->linked_sink=NULL;
++ // Source->source=NULL;
++ //
++ // gWay->ID=handle;
++ //
++ // handle=0;
++ // handle = registerSource(gatewayintialRegistrationList[i].source_name,"default",THIS_DOMAIN,u);
++ // if (handle>0) {
++ // Source->source=so;
++ // Source->ID=handle;
++ // Source->name=so->name;
++ //
++ // gWay->source=so->name;
++ // gWay->sinkID=registerSink(gatewayList[i].sink_name,"default",gatewayList[i].domain_name,u);
++ // gWay->sinks=gatewayList[i].sink_name;
++ // gWay->sourceID=handle;
++ //
++ //
++ // PA_LLIST_PREPEND(struct genGateways,u->listGateways,gWay);
++ // PA_LLIST_PREPEND(struct genSink,u->listSources,Source);
++ // } else {
++ // pa_log("GW Sink register failed");
++ // break;
++ // }
++ // } else {
++ // pa_log("GW register failed");
++ // }
++ // }
++ // }
++ // if ((strcmp(so->name,"null.monitor") ==0) && !is_gw) {
++ // pa_log ("found null source"); //do nothing, no worth it
++ // } else if (!is_gw){
++ // handle=0;
++ // handle=registerSource(so->name,"default",THIS_DOMAIN,u);
++ // if (handle>0) {
++ // struct genSource* Source=NULL;
++ // Source = pa_xnew0(struct genSource, 1);
++ // Source->linked_sink=NULL;
++ // Source->source=NULL;
++ //
++ // Source->source=so;
++ // Source->ID=handle;
++ // Source->name=so->name;
++ // PA_LLIST_PREPEND(struct genSource,u->listSources,Source);
++ // } else {
++ // pa_log("Source register failed");
++ // }
++ // }
++ // }
++
++ //Real stuff is over, now we start faking Sources
++ struct clientSource* clSource=NULL;
++ PA_LLIST_FOREACH(clSource,u->listClientSources) {
++ int handle=0;
++ handle=registerSource(clSource->name,clSource->Audioclass,THIS_DOMAIN,u);
++ if (handle>0) {
++ struct genSource* Source=NULL;
++ Source = pa_xnew0(struct genSource, 1);
++ Source->linked_sink=NULL;
++ Source->source=NULL;
++
++ Source->name=clSource->name;
++ Source->ID=handle;
++ struct genSink* Sink=NULL;
++ PA_LLIST_FOREACH(Sink,u->listSinks) {
++ if (Sink->sink->index==0) {
++ pa_log("Attaching sink");
++ Source->linked_sink=Sink->sink;
++ }
++ }
++
++ PA_LLIST_PREPEND(struct genSource,u->listSources,Source);
++ } else {
++ pa_log("Source register failed");
++ }
++ }
++
++ struct clientSink* clSink=NULL;
++ pa_sink* cs;
++ uint32_t idx_s=0;
++ PA_LLIST_FOREACH(clSink,u->listClientSinks) {
++ int handle=0;
++ handle=registerSink(clSink->name,clSink->Audioclass,THIS_DOMAIN,u);
++ if (handle>0) {
++ struct genSink* Sink=NULL;
++ Sink = pa_xnew0(struct genSink, 1);
++ Sink->name=clSink->name;
++ Sink->ID=handle;
++ idx_s=0;
++ PA_IDXSET_FOREACH(cs, u->core->sinks, idx_s) {
++ if (strcmp(cs->name,Sink->name)==0) {
++ Sink->sink=cs;
++ }
++ }
++ PA_LLIST_PREPEND(struct genSink,u->listSinks,Sink);
++ } else {
++ pa_log("Source register failed");
++ }
++ }
++
++ struct clientGateWays* clGateway=NULL;
++ pa_source* so;
++ pa_sink* si;
++ uint32_t idx;
++ int handle=0;
++ PA_LLIST_FOREACH(clGateway,u->listCLientGateways) {
++ //make a difference according to the type of gateway:
++ if (clGateway->direction==gw_out) {
++ handle=registerGateway(clGateway->name,clGateway->sink_name,clGateway->source_name,clGateway->domain_name,THIS_DOMAIN,THIS_DOMAIN,u);
++ if (handle>0) {
++
++ struct genGateways* gWay=NULL;
++ gWay= pa_xnew0(struct genGateways, 1);
++ struct genSink* Sink=NULL;
++ Sink= pa_xnew(struct genSink, 1);
++ Sink->sink=NULL;
++ gWay->ID=handle;
++
++ handle=0;
++ handle = registerSink(clGateway->sink_name,"default",THIS_DOMAIN,u);
++ if (handle>0) {
++ PA_IDXSET_FOREACH(si, u->core->sinks, idx) {
++ if (strcmp(si->name,clGateway->sink_name)==0) {
++ pa_log("match sink! %s",clGateway->sink_name);
++ Sink->sink=si;
++ Sink->ID=handle;
++ Sink->name=si->name;
++ gWay->sinks=si->name;
++ }
++ }
++ gWay->sourceID=registerSource(clGateway->source_name,"default",clGateway->domain_name,u);
++ gWay->source=clGateway->source_name;
++ gWay->sinkID=handle;
++
++ PA_LLIST_PREPEND(struct genGateways,u->listGateways,gWay);
++ PA_LLIST_PREPEND(struct genSink,u->listSinks,Sink);
++
++ } else {
++ pa_log("GW Sink register failed");
++ break;
++ }
++ } else {
++ pa_log("GW register failed");
++ }
++ } else {
++ handle=registerGateway(clGateway->name,clGateway->sink_name,clGateway->source_name,THIS_DOMAIN,clGateway->domain_name,THIS_DOMAIN,u);
++ if (handle>0) {
++
++ struct genGateways* gWay=NULL;
++ gWay= pa_xnew0(struct genGateways, 1);
++
++ struct genSource* Source=NULL;
++ Source= pa_xnew(struct genSource, 1);
++ Source->linked_sink=NULL;
++ Source->source=NULL;
++ gWay->ID=handle;
++
++ handle=0;
++ handle = registerSource(clGateway->source_name,"default",THIS_DOMAIN,u);
++ if (handle>0) {
++ PA_IDXSET_FOREACH(so, u->core->sources, idx) {
++ if (strcmp(so->name,clGateway->source_name)==0) {
++ Source->source=so;
++ Source->ID=handle;
++ Source->name=so->name;
++ gWay->source=so->name;
++ }
++ }
++ gWay->sinkID=registerSink(clGateway->sink_name,"default",clGateway->domain_name,u);
++ gWay->sinks=clGateway->sink_name;
++ gWay->sourceID=handle;
++
++ PA_LLIST_PREPEND(struct genGateways,u->listGateways,gWay);
++ PA_LLIST_PREPEND(struct genSource,u->listSources,Source);
++
++ } else {
++ pa_log("GW Sink register failed");
++ break;
++ }
++ } else {
++ pa_log("GW register failed");
++ }
++ }
++ }
++ }
++
++ static pa_hook_result_t newSinkInput_cb(pa_core *c, pa_sink_input_new_data *s, void* userdata) {
++ struct userdata *u = userdata;
++
++ //TODO: ok, one day the pure matching of application names should be changed to grap Process IDs.
++ //But for now, we hook on the name
++
++ pa_assert(c);
++ pa_assert(s);
++ pa_assert(u);
++
++ // There's no point in doing anything if the core is shut down anyway
++ if (c->state == PA_CORE_SHUTDOWN)
++ return PA_HOOK_OK;
++
++ //Do we know the client?
++ char* client=pa_proplist_gets(s->proplist,PA_PROP_APPLICATION_NAME);
++ struct genSource* Source=NULL;
++ pa_log("Callback called %s",client);
++
++ PA_LLIST_FOREACH(Source,u->listSources) {
++ if (strcmp(Source->name,client)==0) {
++ if (Source->linked_sink) {
++ pa_log("Client %s %s",Source->name,Source->linked_sink->name);
++ s->sink=Source->linked_sink;
++ }
++ }
++ }
++ return PA_HOOK_OK;
++ }
++
++ static DBusHandlerResult signal_handler (DBusConnection *c, DBusMessage *m, void *userdata) {
++ struct userdata *u = userdata;
++ const char *path;
++
++ pa_log("message handler called\n");
++ pa_assert(u);
++ path = dbus_message_get_path(m);
++ if (pa_streq(path, OBJECT_PATH)) {
++ if (dbus_message_is_method_call(m, SERVICE_NAME, "connect")) {
++ pa_log("Connect called");
++ DbusHandleConnect(c, m, u);
++ } else if (dbus_message_is_method_call(m, SERVICE_NAME, "disconnect")) {
++ pa_log("Disconnect called");
++ DBusHandleDisconnect(c, m, u);
++ } else if (dbus_message_is_method_call(m, SERVICE_NAME, "setSourceVolume")) {
++ pa_log("setSourceVolume called");
++ DbusHandleSetSourceVolume(c, m, u);
++ } else if (dbus_message_is_method_call(m, SERVICE_NAME, "setSinkVolume")) {
++ pa_log("setSinkVolume called");
++ DbusHandleSetSinkVolume(c, m, u);
++ } else if (dbus_message_is_method_call(m, SERVICE_NAME, "muteSource")) {
++ pa_log("muteSource called");
++ DbusHandleMuteSource(c, m, u);
++ } else if (dbus_message_is_method_call(m, SERVICE_NAME, "muteSink")) {
++ pa_log("muteSink called");
++ DbusHandleMuteSink(c, m, u);
++ } else if (dbus_message_is_method_call(m, SERVICE_NAME, "unmuteSink")) {
++ pa_log("unmuteSink called");
++ DbusHandleUmuteSink(c, m, u);
++ } else if (dbus_message_is_method_call(m, SERVICE_NAME, "unmuteSource")) {
++ pa_log("unmuteSource called");
++ DbusHandleUmuteSource(c, m, u);
++ } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
++ const char *xml = PULSE_INTROSPECT_XML;
++ pa_log(xml);
++ DBusMessage *r = NULL;
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ pa_assert_se(dbus_message_append_args(
++ r,
++ DBUS_TYPE_STRING, &xml,
++ DBUS_TYPE_INVALID));
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++ }
++ } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
++ const char *xml = ROOT_INTROSPECT_XML;
++ pa_log(xml);
++ DBusMessage *r = NULL;
++ pa_assert_se(r = dbus_message_new_method_return(m));
++ pa_assert_se(dbus_message_append_args(
++ r,
++ DBUS_TYPE_STRING, &xml,
++ DBUS_TYPE_INVALID));
++ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), r, NULL));
++ dbus_message_unref(r);
++ }
++
++ if (dbus_message_is_signal(m, ROUTING_INTERFACE_NAME, "signal_systemReady")) {
++ pa_log("Received Signal signal_systemReady");
++ intialRegistration(c,u);
++ }
++ return DBUS_HANDLER_RESULT_HANDLED;
++ }
++
++ void loadConfigFile(const char* filename, void* userdata) {
++ struct userdata *u = userdata;
++ FILE* f=NULL;
++ char* ret;
++ if (filename) {
++
++ if (!(f = fopen(filename, "r"))) {
++ pa_log(_("Failed to open file '%s'"), filename);
++ goto finish;
++ }
++
++ while (!feof(f)) {
++ char l[4096];
++
++ if (!fgets(l, sizeof(l), f)) {
++ if (feof(f))
++ break;
++ goto finish;
++ }
++
++ char* pointer=(char*)l;
++ int len = strlen(pointer);
++ if( pointer[len-1] == '\n' )
++ pointer[len-1] = 0;
++ char* type=strsep(&pointer,":");
++ if (strcmp(type,"Source")==0) {
++ ret=strsep(&pointer,",");
++ struct clientSource* clSource=NULL;
++ clSource= pa_xnew0(struct clientSource, 1);
++ strcpy(clSource->name,ret);
++ strcpy(clSource->Audioclass,pointer);
++ PA_LLIST_PREPEND(struct clientSource,u->listClientSources,clSource);
++ } else if (strcmp(type,"Sink")==0) {
++ ret=strsep(&pointer,",");
++ struct clientSink* clSink=NULL;
++ clSink= pa_xnew0(struct clientSink, 1);
++ strcpy(clSink->name,ret);
++ strcpy(clSink->Audioclass,pointer);
++ PA_LLIST_PREPEND(struct clientSink,u->listClientSinks,clSink);
++ } else if (strcmp(type,"Gateway")==0) {
++ struct clientGateWays* clGateway=NULL;
++ clGateway= pa_xnew0(struct clientGateWays, 1);
++ ret=strsep(&pointer,",");
++ strcpy(clGateway->name,ret);
++ ret=strsep(&pointer,",");
++ strcpy(clGateway->sink_name,ret);
++ ret=strsep(&pointer,",");
++ strcpy(clGateway->source_name,ret);
++ ret=strsep(&pointer,",");
++ strcpy(clGateway->domain_name,ret);
++ ret=strsep(&pointer,",");
++ if (strcmp(ret,"gw_out")==0) {
++ clGateway->direction=gw_out;
++ } else if (strcmp(ret,"gw_in")==0) {
++ clGateway->direction=gw_in;
++ }
++ PA_LLIST_PREPEND(struct clientGateWays,u->listCLientGateways,clGateway);
++ }
++ }
++ }
++ finish:
++ if (f) fclose(f);
++ }
++
++ int pa__init(pa_module*m) {
++ pa_modargs *ma = NULL;
++ const char* file_name;
++ pa_log("Started module Genivi !!!!!!*********************************");
++ pa_assert(m);
++ DBusError error;
++ static const DBusObjectPathVTable vtable_root = {
++ .message_function = signal_handler,
++ };
++
++ if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
++ pa_log("Failed to parse module arguments.");
++ goto fail;
++ }
++
++ file_name= pa_modargs_get_value(ma, "file_name", NULL);
++ pa_log("filename %s",file_name);
++
++ //userdata is used to pass data around in the different callbacks
++ struct userdata *u;
++
++ dbus_error_init(&error);
++
++ m->userdata = u = pa_xnew(struct userdata, 1);
++ u->core=m->core;
++ pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) newSinkInput_cb, u);
++
++ if (!(u->bus = pa_dbus_bus_get(m->core, DBUS_BUS_SESSION, &error))) {
++ pa_log("Failed to get session bus connection: %s", error.message);
++ goto fail;
++ }
++
++ //initialize the Linked Lists which hold our data
++ PA_LLIST_HEAD_INIT(struct genSink,u->listSinks);
++ PA_LLIST_HEAD_INIT(struct genSource,u->listSources);
++ PA_LLIST_HEAD_INIT(struct genModule,u->listModules);
++ PA_LLIST_HEAD_INIT(struct genGateways,u->listGateways);
++ PA_LLIST_HEAD_INIT(struct genConnections,u->listConnections);
++ PA_LLIST_HEAD_INIT(struct clientSink,u->listClientSinks);
++ PA_LLIST_HEAD_INIT(struct clientSource,u->listClientSources);
++ PA_LLIST_HEAD_INIT(struct clientGateWays,u->listCLientGateways);
++
++ loadConfigFile(file_name,u);
++
++ //Register signalhandler for signals coming from Routing interface
++ dbus_bus_add_match(pa_dbus_connection_get(u->bus), "type=\'signal\',interface=\'com.genivi.routing\'",NULL);
++ dbus_connection_add_filter (pa_dbus_connection_get(u->bus), signal_handler, u, NULL);
++ dbus_connection_flush(pa_dbus_connection_get(u->bus));
++
++ pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(u->bus), OBJECT_ROOT, &vtable_root, u));
++
++ if (dbus_bus_request_name(pa_dbus_connection_get(u->bus), SERVICE_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
++ pa_log("Failed to request service name " SERVICE_NAME ": %s", error.message);
++ goto fail;
++ }
++
++
++ //intialRegistration(u->core,u);
++
++ //int d=registerSource(name, node, name,u);
++
++ //TODO:
++ //the loopback module is loaded via the default file because loading it here fails with segfault.
++
++
++
++
++
++ return 0;
++ fail:
++ pa__done(m);
++
++ dbus_error_free(&error);
++
++ return -1;
++ }
++
++ void pa__done(pa_module*m) {
++ }
+diff -crBN pulseaudio-0.9.22/src/modules/module-genivi-symdef.h pulseaudio-0.9.22-patched/src/modules/module-genivi-symdef.h
+*** pulseaudio-0.9.22/src/modules/module-genivi-symdef.h 1970-01-01 01:00:00.000000000 +0100
+--- pulseaudio-0.9.22-patched/src/modules/module-genivi-symdef.h 2011-06-30 15:16:20.232519999 +0200
+***************
+*** 0 ****
+--- 1,21 ----
++ #ifndef foomodulegenivifoo
++ #define foomodulegenivifoo
++
++ #include <pulsecore/core.h>
++ #include <pulsecore/module.h>
++ #include <pulsecore/macro.h>
++
++ #define pa__init module_always_sink_LTX_pa__init
++ #define pa__done module_always_sink_LTX_pa__done
++ #define pa__get_author module_always_sink_LTX_pa__get_author
++ #define pa__get_description module_always_sink_LTX_pa__get_description
++ #define pa__get_usage module_always_sink_LTX_pa__get_usage
++ #define pa__get_version module_always_sink_LTX_pa__get_version
++ #define pa__get_deprecated module_always_sink_LTX_pa__get_deprecated
++ #define pa__load_once module_always_sink_LTX_pa__load_once
++ #define pa__get_n_used module_always_sink_LTX_pa__get_n_used
++
++ int pa__init(pa_module*m);
++ void pa__done(pa_module*m);
++
++ #endif
+diff -crBN pulseaudio-0.9.22/src/SourceList.conf pulseaudio-0.9.22-patched/src/SourceList.conf
+*** pulseaudio-0.9.22/src/SourceList.conf 1970-01-01 01:00:00.000000000 +0100
+--- pulseaudio-0.9.22-patched/src/SourceList.conf 2011-06-30 15:16:20.232519999 +0200
+***************
+*** 0 ****
+--- 1,6 ----
++ Rhythmbox,default
++ Totem Movie Player,default
++ navigation,nav
++ player,default
++ radio,rad
++ ta,ta
+diff -crBN pulseaudio-0.9.22/src/test.pa pulseaudio-0.9.22-patched/src/test.pa
+*** pulseaudio-0.9.22/src/test.pa 1970-01-01 01:00:00.000000000 +0100
+--- pulseaudio-0.9.22-patched/src/test.pa 2011-06-30 15:16:20.232519999 +0200
+***************
+*** 0 ****
+--- 1,54 ----
++ #!/usr/local/bin/pulseaudio -nF
++ #
++ # This file is part of PulseAudio.
++ #
++ # 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 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.
++
++ # This startup script is used only if PulseAudio is started per-user
++ # (i.e. not in system mode)
++
++ .nofail
++
++ ### Load something into the sample cache
++ #load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav
++ #load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
++ #load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav
++ #load-sample-lazy pulse-access /usr/share/sounds/generic.wav
++
++ .fail
++
++
++ ### Load audio drivers statically (it's probably better to not load
++ ### these drivers manually, but instead use module-hal-detect --
++ ### see below -- for doing this automatically)
++ load-module module-alsa-sink
++ load-module module-alsa-source
++ load-module module-null-sink
++ load-module module-pipe-sink
++ load-module module-native-protocol-tcp
++ load-module module-loopback
++ load-module module-jack-source
++ load-module module-jack-sink
++ load-module module-tunnel-sink sink_name=tunnel server=10.253.201.82
++ load-module module-genivi file_name=/home/blacky/workspace/pulseaudio-0.9.22/src/Genivi.conf
++ #load-module module-null-sink sink_name="rtp"
++ #load-module module-rtp-send source="rtp.monitor" destination="224.0.0.56" port="5004"
++
++
++ load-module module-udev-detect
++
++ ### Make some devices default
++ set-default-sink null
++ set-default-source null-monitor