scripting: support for zone based routing in application classes
[profile/ivi/pulseaudio-module-murphy-ivi.git] / murphy / utils.c
index 5cb0f19..e1c6751 100644 (file)
 #include <pulsecore/pulsecore-config.h>
 
 #include <pulsecore/core-util.h>
-#include <pulsecore/card.h>
 #include <pulsecore/sink.h>
+#include <pulsecore/card.h>
 #include <pulsecore/source.h>
 #include <pulsecore/sink-input.h>
+#include <pulsecore/source-output.h>
 
 #include "userdata.h"
 #include "utils.h"
 #include "node.h"
 
-#ifndef DEFAULT_CONFIG_DIR
-#define DEFAULT_CONFIG_DIR "/etc/pulse"
-#endif
 
 #define DEFAULT_NULL_SINK_NAME "null.mir"
 
@@ -57,7 +55,8 @@ struct pa_null_sink {
 
 static uint32_t stamp;
 
-static char *sink_input_name(pa_proplist *);
+static char *stream_name(pa_proplist *);
+static pa_bool_t get_unsigned_property(pa_proplist *, const char *,uint32_t *);
 
 
 pa_null_sink *pa_utils_create_null_sink(struct userdata *u, const char *name)
@@ -123,7 +122,7 @@ pa_sink *pa_utils_get_null_sink(struct userdata *u)
 {
     pa_core *core;
     pa_null_sink *ns;
-    
+
     pa_assert(u);
     pa_assert_se((core = u->core));
     pa_assert_se((ns = u->nullsink));
@@ -131,6 +130,13 @@ pa_sink *pa_utils_get_null_sink(struct userdata *u)
     return pa_idxset_get_by_index(core->sinks, ns->sink_index);
 }
 
+pa_source *pa_utils_get_null_source(struct userdata *u)
+{
+    pa_sink *ns = pa_utils_get_null_sink(u);
+
+    return ns ? ns->monitor_source : NULL;
+}
+
 
 
 char *pa_utils_get_card_name(pa_card *card)
@@ -138,6 +144,24 @@ char *pa_utils_get_card_name(pa_card *card)
     return (card && card->name) ? card->name : "<unknown>";
 }
 
+char *pa_utils_get_card_bus(pa_card *card)
+{
+    const char *bus = NULL;
+    char       *name;
+
+    if (card && !(bus = pa_proplist_gets(card->proplist,PA_PROP_DEVICE_BUS))) {
+        name = pa_utils_get_card_name(card);
+        if (!strncmp(name, "alsa_card.", 10)) {
+            if (!strncmp(name + 10, "pci-", 4))
+                bus = "pci";
+            else if (!strncmp(name + 10, "usb-", 4))
+                bus = "usb";
+        }
+    }
+
+    return (char *)bus;
+}
+
 char *pa_utils_get_sink_name(pa_sink *sink)
 {
     return (sink && sink->name) ? sink->name : "<unknown>";
@@ -152,9 +176,9 @@ char *pa_utils_get_sink_input_name(pa_sink_input *sinp)
 {
     char *name;
 
-    if (sinp && (name = sink_input_name(sinp->proplist)))
+    if (sinp && (name = stream_name(sinp->proplist)))
         return name;
-    
+
     return "<unknown>";
 }
 
@@ -162,16 +186,48 @@ char *pa_utils_get_sink_input_name_from_data(pa_sink_input_new_data *data)
 {
     char *name;
 
-    if (data && (name = sink_input_name(data->proplist)))
+    if (data && (name = stream_name(data->proplist)))
         return name;
-    
+
     return "<unknown>";
 }
 
 
-void pa_utils_set_stream_routing_properties(pa_proplist *pl,
-                                            int          styp,
-                                            pa_sink     *sink)
+char *pa_utils_get_source_output_name(pa_source_output *sout)
+{
+    char *name;
+
+    if (sout && (name = stream_name(sout->proplist)))
+        return name;
+
+    return "<unknown>";
+}
+
+char *pa_utils_get_source_output_name_from_data(pa_source_output_new_data*data)
+{
+    char *name;
+
+    if (data && (name = stream_name(data->proplist)))
+        return name;
+
+    return "<unknown>";
+}
+
+char *pa_utils_get_zone(pa_proplist *pl)
+{
+    const char *zone;
+
+    pa_assert(pl);
+
+    if (!(zone = pa_proplist_gets(pl, PA_PROP_ZONE_NAME)))
+        zone = PA_ZONE_NAME_DEFAULT;
+
+    return (char *)zone;
+}
+
+pa_bool_t pa_utils_set_stream_routing_properties(pa_proplist *pl,
+                                                 int          styp,
+                                                 void        *target)
 {
     const char    *clnam;
     const char    *method;
@@ -179,17 +235,35 @@ void pa_utils_set_stream_routing_properties(pa_proplist *pl,
 
     pa_assert(pl);
     pa_assert(styp >= 0);
-    
+
     snprintf(clid, sizeof(clid), "%d", styp);
     clnam  = mir_node_type_str(styp);
-    method = sink ? PA_ROUTING_EXPLICIT : PA_ROUTING_DEFAULT;
+    method = target ? PA_ROUTING_EXPLICIT : PA_ROUTING_DEFAULT;
 
     if (pa_proplist_sets(pl, PA_PROP_ROUTING_CLASS_NAME, clnam ) < 0 ||
         pa_proplist_sets(pl, PA_PROP_ROUTING_CLASS_ID  , clid  ) < 0 ||
         pa_proplist_sets(pl, PA_PROP_ROUTING_METHOD    , method) < 0  )
     {
-        pa_log("failed to set some property on sink-input");
+        pa_log("failed to set some stream property");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+pa_bool_t pa_utils_unset_stream_routing_properties(pa_proplist *pl)
+{
+    pa_assert(pl);
+
+    if (pa_proplist_unset(pl, PA_PROP_ROUTING_CLASS_NAME) < 0 ||
+        pa_proplist_unset(pl, PA_PROP_ROUTING_CLASS_ID  ) < 0 ||
+        pa_proplist_unset(pl, PA_PROP_ROUTING_METHOD    ) < 0  )
+    {
+        pa_log("failed to unset some stream property");
+        return FALSE;
     }
+
+    return TRUE;
 }
 
 void pa_utils_set_stream_routing_method_property(pa_proplist *pl,
@@ -198,7 +272,7 @@ void pa_utils_set_stream_routing_method_property(pa_proplist *pl,
     const char *method = explicit ? PA_ROUTING_EXPLICIT : PA_ROUTING_DEFAULT;
 
     pa_assert(pl);
-    
+
     if (pa_proplist_sets(pl, PA_PROP_ROUTING_METHOD, method) < 0) {
         pa_log("failed to set routing method property on sink-input");
     }
@@ -237,7 +311,232 @@ int pa_utils_get_stream_class(pa_proplist *pl)
 }
 
 
-static char *sink_input_name(pa_proplist *pl)
+pa_bool_t pa_utils_set_resource_properties(pa_proplist *pl,
+                                           pa_nodeset_resdef *resdef)
+{
+    char priority[32];
+    char rsetflags[32];
+    char audioflags[32];
+
+    pa_assert(pl);
+
+    if (!resdef)
+        return FALSE;
+
+    snprintf(priority  , sizeof(priority)  , "%d", resdef->priority   );
+    snprintf(rsetflags , sizeof(rsetflags) , "%d", resdef->flags.rset );
+    snprintf(audioflags, sizeof(audioflags), "%d", resdef->flags.audio);
+
+    if (pa_proplist_sets(pl, PA_PROP_RESOURCE_PRIORITY   , priority  ) < 0 ||
+        pa_proplist_sets(pl, PA_PROP_RESOURCE_SET_FLAGS  , rsetflags ) < 0 ||
+        pa_proplist_sets(pl, PA_PROP_RESOURCE_AUDIO_FLAGS, audioflags) < 0  )
+    {
+        pa_log("failed to set some resource property");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+pa_bool_t pa_utils_unset_resource_properties(pa_proplist *pl)
+{
+    pa_assert(pl);
+
+    if (pa_proplist_unset(pl, PA_PROP_RESOURCE_PRIORITY   ) < 0 ||
+        pa_proplist_unset(pl, PA_PROP_RESOURCE_SET_FLAGS  ) < 0 ||
+        pa_proplist_unset(pl, PA_PROP_RESOURCE_AUDIO_FLAGS) < 0  )
+    {
+        pa_log("failed to unset some resource property");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+pa_nodeset_resdef *pa_utils_get_resource_properties(pa_proplist *pl,
+                                                    pa_nodeset_resdef *rd)
+{
+    pa_assert(pl);
+    pa_assert(rd);
+
+    int success;
+
+    memset(rd, 0, sizeof(pa_nodeset_resdef));
+
+    success  = get_unsigned_property(pl, PA_PROP_RESOURCE_PRIORITY,
+                                     &rd->priority);
+    success |= get_unsigned_property(pl, PA_PROP_RESOURCE_SET_FLAGS,
+                                     &rd->flags.rset);
+    success |= get_unsigned_property(pl, PA_PROP_RESOURCE_AUDIO_FLAGS,
+                                     &rd->flags.audio);
+    
+    return success ? rd : NULL;
+}
+
+
+static pa_bool_t get_unsigned_property(pa_proplist *pl,
+                                       const char *name,
+                                       uint32_t *value)
+{
+    const char *str;
+    char *e;
+
+    pa_assert(pl);
+    pa_assert(name);
+    pa_assert(value);
+
+    if (!(str = pa_proplist_gets(pl, name))) {
+        *value = 0;
+        return FALSE;
+    }
+
+    *value = strtoul(str, &e, 10);
+
+    if (e == str || *e) {
+        *value = 0;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+void pa_utils_set_port_properties(pa_device_port *port, mir_node *node)
+{
+    const char *profile;
+    char propnam[512];
+    char nodeidx[256];
+
+    pa_assert(port);
+    pa_assert(port->proplist);
+    pa_assert(node);
+    pa_assert_se((profile = node->pacard.profile));
+
+    snprintf(propnam, sizeof(propnam), "%s.%s", PA_PROP_NODE_INDEX, profile);
+    snprintf(nodeidx, sizeof(nodeidx), "%u", node->index);
+
+    pa_proplist_sets(port->proplist, propnam, nodeidx);
+}
+
+mir_node *pa_utils_get_node_from_port(struct userdata *u,
+                                      pa_device_port *port,
+                                      void **state)
+{
+    const char *name;
+    const char *value;
+    char *e;
+    uint32_t index = PA_IDXSET_INVALID;
+    mir_node *node = NULL;
+
+    pa_assert(u);
+    pa_assert(port);
+    pa_assert(port->proplist);
+
+    while ((name = pa_proplist_iterate(port->proplist, state))) {
+        if (!strncmp(name, PA_PROP_NODE_INDEX, sizeof(PA_PROP_NODE_INDEX)-1)) {
+            if ((value = pa_proplist_gets(port->proplist, name))) {
+                index = strtoul(value, &e, 10);
+                node = NULL;
+
+                if (value[0] && !e[0])
+                    node = mir_node_find_by_index(u, index);
+                
+                if (node)
+                    return node;
+
+                pa_log("Can't find node %u for port %s", index, port->name);
+            }
+        }
+    }
+
+    return NULL;
+}
+
+mir_node *pa_utils_get_node_from_stream(struct userdata *u,
+                                        mir_direction    type,
+                                        void            *ptr)
+{
+    pa_sink_input    *sinp;
+    pa_source_output *sout;
+    pa_proplist      *pl;
+    mir_node         *node;
+    const char       *index_str;
+    uint32_t          index = PA_IDXSET_INVALID;
+    char             *e;
+    char              name[256];
+
+    pa_assert(u);
+    pa_assert(ptr);
+    pa_assert(type == mir_input || type == mir_output);
+
+    if (type == mir_input) {
+        sinp = (pa_sink_input *)ptr;
+        pl = sinp->proplist;
+        snprintf(name, sizeof(name), "sink-input.%u", sinp->index);
+    }
+    else {
+        sout = (pa_source_output *)ptr;
+        pl = sout->proplist;
+        snprintf(name, sizeof(name), "source-output.%u", sout->index);
+    }
+
+
+    if ((index_str = pa_proplist_gets(pl, PA_PROP_NODE_INDEX))) {
+        index = strtoul(index_str, &e, 10);
+        if (e != index_str && *e == '\0') {
+            if ((node = mir_node_find_by_index(u, index)))
+                return node;
+
+            pa_log_debug("can't find find node for %s", name);
+        }
+    }
+
+    return NULL;
+}
+
+mir_node *pa_utils_get_node_from_data(struct userdata *u,
+                                      mir_direction    type,
+                                      void            *ptr)
+{
+    pa_sink_input_new_data *sinp;
+    pa_source_output_new_data *sout;
+    pa_proplist  *pl;
+    mir_node     *node;
+    const char   *index_str;
+    uint32_t      index = PA_IDXSET_INVALID;
+    char         *e;
+    char          name[256];
+
+    pa_assert(u);
+    pa_assert(ptr);
+    pa_assert(type == mir_input || type == mir_output);
+
+    if (type == mir_input) {
+        sinp = (pa_sink_input_new_data *)ptr;
+        pl = sinp->proplist;
+        snprintf(name, sizeof(name), "sink-input");
+    }
+    else {
+        sout = (pa_source_output_new_data *)ptr;
+        pl = sout->proplist;
+        snprintf(name, sizeof(name), "source-output");
+    }
+
+
+    if ((index_str = pa_proplist_gets(pl, PA_PROP_NODE_INDEX))) {
+        index = strtoul(index_str, &e, 10);
+        if (e != index_str && *e == '\0') {
+            if ((node = mir_node_find_by_index(u, index)))
+                return node;
+
+            pa_log_debug("can't find find node for %s", name);
+        }
+    }
+
+    return NULL;
+}
+
+static char *stream_name(pa_proplist *pl)
 {
     const char  *appnam;
     const char  *binnam;
@@ -252,13 +551,14 @@ static char *sink_input_name(pa_proplist *pl)
 }
 
 
-const char *pa_utils_file_path(const char *file, char *buf, size_t len)
+const char *pa_utils_file_path(const char *dir, const char *file,
+                               char *buf, size_t len)
 {
     pa_assert(file);
     pa_assert(buf);
     pa_assert(len > 0);
 
-    snprintf(buf, len, "%s/%s", DEFAULT_CONFIG_DIR, file);
+    snprintf(buf, len, "%s/%s", dir, file);
 
     return buf;
 }
@@ -276,7 +576,6 @@ uint32_t pa_utils_get_stamp(void)
 
 
 
-
 /*
  * Local Variables:
  * c-basic-offset: 4