add more configurability for default resource sets
authorJanos Kovacs <jankovac503@gmail.com>
Thu, 7 Feb 2013 00:28:05 +0000 (02:28 +0200)
committerJanos Kovacs <jankovac503@gmail.com>
Thu, 7 Feb 2013 00:28:05 +0000 (02:28 +0200)
15 files changed:
murphy/classify.c
murphy/classify.h
murphy/discover.c
murphy/murphy-config.c
murphy/murphy-ivi.lua
murphy/murphyif.c
murphy/murphyif.h
murphy/node.c
murphy/node.h
murphy/scripting.c
murphy/stream-state.c
murphy/stream-state.h
murphy/userdata.h
murphy/utils.c
murphy/utils.h

index 29435c5..cecc944 100644 (file)
@@ -255,24 +255,37 @@ void pa_classify_guess_device_node_type_and_name(mir_node   *node,
 
 
 mir_node_type pa_classify_guess_stream_node_type(struct userdata *u,
-                                                 pa_proplist *pl)
+                                                 pa_proplist *pl,
+                                                 pa_nodeset_resdef **resdef)
 {
-    mir_node_type  type;
-    const char    *role;
-    const char    *bin;
+    pa_nodeset_map *map;
+    const char     *role;
+    const char     *bin;
 
     pa_assert(u);
     pa_assert(pl);
 
-    if ((bin  = pa_proplist_gets(pl, PA_PROP_APPLICATION_PROCESS_BINARY)) &&
-        (type = pa_nodeset_get_type_by_binary(u, bin)))
-        return type;
 
-    if ((role = pa_proplist_gets(pl, PA_PROP_MEDIA_ROLE)) &&
-        (type = pa_nodeset_get_type_by_role(u, role)))
-        return type;
+    do {
+        if ((bin = pa_proplist_gets(pl, PA_PROP_APPLICATION_PROCESS_BINARY)) &&
+            (map = pa_nodeset_get_map_by_binary(u, bin)))
+            break;
+
+        if ((role = pa_proplist_gets(pl, PA_PROP_MEDIA_ROLE)) &&
+            (map = pa_nodeset_get_map_by_role(u, role)))
+            break;
+
+        if (resdef)
+            *resdef = NULL;
+
+        return role ? mir_node_type_unknown : mir_player;
+
+    } while (0);
+
+    if (resdef)
+        *resdef = map->resdef;
 
-    return role ? mir_node_type_unknown : mir_player;
+    return map->type;
 }
 
 mir_node_type pa_classify_guess_application_class(mir_node *node)
index 93deffb..85d1bdc 100644 (file)
@@ -30,7 +30,8 @@ pa_bool_t pa_classify_node_by_property(mir_node *, pa_proplist *);
 void pa_classify_guess_device_node_type_and_name(mir_node*, const char *,
                                                  const char *);
 mir_node_type pa_classify_guess_stream_node_type(struct userdata *,
-                                                 pa_proplist *);
+                                                 pa_proplist *,
+                                                 pa_nodeset_resdef **);
 mir_node_type pa_classify_guess_application_class(mir_node *);
 
 pa_bool_t pa_classify_multiplex_stream(mir_node *);
index de37621..dd16c2c 100644 (file)
@@ -46,6 +46,7 @@
 #include "utils.h"
 #include "extapi.h"
 #include "stream-state.h"
+#include "murphyif.h"
 
 #define MAX_CARD_TARGET   4
 #define MAX_NAME_LENGTH   256
@@ -679,18 +680,19 @@ void pa_discover_remove_source(struct userdata *u, pa_source *source)
 
 void pa_discover_register_sink_input(struct userdata *u, pa_sink_input *sinp)
 {
-    pa_core       *core;
-    pa_discover   *discover;
-    pa_proplist   *pl;
-    char          *name;
-    const char    *media;
-    mir_node_type  type;
-    mir_node       data;
-    mir_node      *node;
-    mir_node      *target;
-    char           key[256];
-    pa_sink       *sink;
-    const char    *role;
+    pa_core           *core;
+    pa_discover       *discover;
+    pa_proplist       *pl;
+    char              *name;
+    const char        *media;
+    mir_node_type      type;
+    mir_node           data;
+    mir_node          *node;
+    mir_node          *target;
+    char               key[256];
+    pa_sink           *sink;
+    const char        *role;
+    pa_nodeset_resdef *resdef;
 
     pa_assert(u);
     pa_assert(sinp);
@@ -713,7 +715,7 @@ void pa_discover_register_sink_input(struct userdata *u, pa_sink_input *sinp)
 
     pa_log_debug("registering input stream '%s'", name);
 
-    if (!(type = pa_classify_guess_stream_node_type(u, pl))) {
+    if (!(type = pa_classify_guess_stream_node_type(u, pl, &resdef))) {
         pa_log_debug("cant find stream class for '%s'. "
                      "Leaving it alone", name);
         return;
@@ -770,19 +772,20 @@ void pa_discover_register_sink_input(struct userdata *u, pa_sink_input *sinp)
 void pa_discover_preroute_sink_input(struct userdata *u,
                                      pa_sink_input_new_data *data)
 {
-    pa_core       *core;
-    pa_module     *m;
-    pa_proplist   *pl;
-    pa_discover   *discover;
-    pa_multiplex  *multiplex;
-    mir_node       fake;
-    pa_sink       *sink;
-    pa_sink_input *sinp;
-    const char    *mnam;
-    const char    *role;
-    mir_node_type  type;
-    mir_node      *node;
-    pa_muxnode    *mux;
+    pa_core           *core;
+    pa_module         *m;
+    pa_proplist       *pl;
+    pa_discover       *discover;
+    pa_multiplex      *multiplex;
+    mir_node           fake;
+    pa_sink           *sink;
+    pa_sink_input     *sinp;
+    const char        *mnam;
+    const char        *role;
+    mir_node_type      type;
+    mir_node          *node;
+    pa_muxnode        *mux;
+    pa_nodeset_resdef *resdef;
 
     pa_assert(u);
     pa_assert(data);
@@ -823,11 +826,14 @@ void pa_discover_preroute_sink_input(struct userdata *u,
 
             data->sink = NULL;
 
-            type = pa_classify_guess_stream_node_type(u, pl);
+            type = pa_classify_guess_stream_node_type(u, pl, NULL);
         }
         else {
-            type = pa_classify_guess_stream_node_type(u, pl);
-            if (pa_stream_state_start_corked(u, data, type)) {
+            type = pa_classify_guess_stream_node_type(u, pl, &resdef);
+
+            pa_utils_set_resource_properties(pl, resdef);
+
+            if (pa_stream_state_start_corked(u, data, resdef)) {
                 pa_log("start corked");
             }
         }
@@ -867,21 +873,23 @@ void pa_discover_preroute_sink_input(struct userdata *u,
 
 void pa_discover_add_sink_input(struct userdata *u, pa_sink_input *sinp)
 {
-    pa_core        *core;
-    pa_sink        *s;
-    pa_sink_input  *csinp;
-    pa_proplist    *pl;
-    pa_discover    *discover;
-    pa_multiplex   *multiplex;
-    mir_node        data;
-    mir_node       *node;
-    mir_node       *snod;
-    char           *name;
-    const char     *media;
-    mir_node_type   type;
-    char            key[256];
-    pa_bool_t       created;
-    pa_muxnode     *mux;
+    pa_core           *core;
+    pa_sink           *s;
+    pa_sink_input     *csinp;
+    pa_proplist       *pl;
+    pa_discover       *discover;
+    pa_multiplex      *multiplex;
+    mir_node           data;
+    mir_node          *node;
+    mir_node          *snod;
+    char              *name;
+    const char        *media;
+    mir_node_type      type;
+    char               key[256];
+    pa_bool_t          created;
+    pa_muxnode        *mux;
+    pa_nodeset_resdef *resdef;
+    pa_nodeset_resdef  rdbuf;
 
     pa_assert(u);
     pa_assert(sinp);
@@ -890,6 +898,8 @@ void pa_discover_add_sink_input(struct userdata *u, pa_sink_input *sinp)
     pa_assert_se((multiplex = u->multiplex));
     pa_assert_se((pl = sinp->proplist));
 
+    resdef = NULL;
+
     if (!(media = pa_proplist_gets(sinp->proplist, PA_PROP_MEDIA_NAME)))
         media = "<unknown>";
 
@@ -929,8 +939,10 @@ void pa_discover_add_sink_input(struct userdata *u, pa_sink_input *sinp)
 
         pa_log_debug("dealing with new input stream '%s'", name);
 
-        if ((type = get_stream_routing_class(pl)) == mir_node_type_unknown) {
-            if (!(type = pa_classify_guess_stream_node_type(u, pl))) {
+        if ((type = get_stream_routing_class(pl)))
+            resdef = pa_utils_get_resource_properties(pl, &rdbuf);
+        else {
+            if (!(type = pa_classify_guess_stream_node_type(u, pl, &resdef))) {
                 pa_log_debug("cant find stream class for '%s'. "
                              "Leaving it alone", name);
                 return;
@@ -972,6 +984,11 @@ void pa_discover_add_sink_input(struct userdata *u, pa_sink_input *sinp)
             return;
         }
 
+        if (node->rsetid)
+            pa_murphyif_add_node(u, node);
+        else if (resdef)
+            pa_murphyif_create_resource_set(u, node, resdef);
+
         pa_discover_add_node_to_ptr_hash(u, sinp, node);
 
         if (!data.mux)
@@ -1045,18 +1062,19 @@ void pa_discover_remove_sink_input(struct userdata *u, pa_sink_input *sinp)
 void pa_discover_register_source_output(struct userdata  *u,
                                         pa_source_output *sout)
 {
-    pa_core       *core;
-    pa_discover   *discover;
-    pa_proplist   *pl;
-    char          *name;
-    const char    *media;
-    mir_node_type  type;
-    mir_node       data;
-    mir_node      *node;
-    mir_node      *target;
-    char           key[256];
-    pa_source     *source;
-    const char    *role;
+    pa_core           *core;
+    pa_discover       *discover;
+    pa_proplist       *pl;
+    char              *name;
+    const char        *media;
+    mir_node_type      type;
+    mir_node           data;
+    mir_node          *node;
+    mir_node          *target;
+    char               key[256];
+    pa_source         *source;
+    const char        *role;
+    pa_nodeset_resdef *resdef;
 
     pa_assert(u);
     pa_assert(sout);
@@ -1075,7 +1093,7 @@ void pa_discover_register_source_output(struct userdata  *u,
 
     pa_log_debug("registering output stream '%s'", name);
 
-    if (!(type = pa_classify_guess_stream_node_type(u, pl))) {
+    if (!(type = pa_classify_guess_stream_node_type(u, pl, &resdef))) {
         pa_log_debug("cant find stream class for '%s'. "
                      "Leaving it alone", name);
         return;
@@ -1132,16 +1150,17 @@ void pa_discover_register_source_output(struct userdata  *u,
 void pa_discover_preroute_source_output(struct userdata *u,
                                         pa_source_output_new_data *data)
 {
-    pa_core       *core;
-    pa_module     *m;
-    pa_proplist   *pl;
-    pa_discover   *discover;
-    mir_node       fake;
-    pa_source     *source;
-    const char    *mnam;
-    const char    *role;
-    mir_node_type  type;
-    mir_node      *node;
+    pa_core           *core;
+    pa_module         *m;
+    pa_proplist       *pl;
+    pa_discover       *discover;
+    mir_node           fake;
+    pa_source         *source;
+    const char        *mnam;
+    const char        *role;
+    mir_node_type      type;
+    mir_node          *node;
+    pa_nodeset_resdef *resdef;
 
     pa_assert(u);
     pa_assert(data);
@@ -1165,8 +1184,15 @@ void pa_discover_preroute_source_output(struct userdata *u,
         }
 
         data->source = NULL;
+
+        type = pa_classify_guess_stream_node_type(u, pl, NULL);
+    }
+    else {
+        type = pa_classify_guess_stream_node_type(u, pl, &resdef);
+
+        pa_utils_set_resource_properties(pl, resdef);
     }
-    type = pa_classify_guess_stream_node_type(u, pl);
+
     pa_utils_set_stream_routing_properties(pl, type, data->source);
 
     if (!data->source) {
@@ -1199,18 +1225,20 @@ void pa_discover_preroute_source_output(struct userdata *u,
 
 void pa_discover_add_source_output(struct userdata *u, pa_source_output *sout)
 {
-    pa_core        *core;
-    pa_source      *s;
-    pa_proplist    *pl;
-    pa_discover    *discover;
-    mir_node        data;
-    mir_node       *node;
-    mir_node       *snod;
-    char           *name;
-    const char     *media;
-    mir_node_type   type;
-    char            key[256];
-    pa_bool_t       created;
+    pa_core           *core;
+    pa_source         *s;
+    pa_proplist       *pl;
+    pa_discover       *discover;
+    mir_node           data;
+    mir_node          *node;
+    mir_node          *snod;
+    char              *name;
+    const char        *media;
+    mir_node_type      type;
+    char               key[256];
+    pa_bool_t          created;
+    pa_nodeset_resdef *resdef;
+    pa_nodeset_resdef  rdbuf;
 
     pa_assert(u);
     pa_assert(sout);
@@ -1218,6 +1246,8 @@ void pa_discover_add_source_output(struct userdata *u, pa_source_output *sout)
     pa_assert_se((discover = u->discover));
     pa_assert_se((pl = sout->proplist));
 
+    resdef = NULL;
+
     if (!(media = pa_proplist_gets(sout->proplist, PA_PROP_MEDIA_NAME)))
         media = "<unknown>";
 
@@ -1242,8 +1272,10 @@ void pa_discover_add_source_output(struct userdata *u, pa_source_output *sout)
 
         pa_log_debug("dealing with new output stream '%s'", name);
 
-        if ((type = get_stream_routing_class(pl)) == mir_node_type_unknown) {
-            if (!(type = pa_classify_guess_stream_node_type(u, pl))) {
+        if ((type = get_stream_routing_class(pl)))
+            resdef = pa_utils_get_resource_properties(pl, &rdbuf);
+        else {
+            if (!(type = pa_classify_guess_stream_node_type(u, pl, &resdef))) {
                 pa_log_debug("cant find stream class for '%s'. "
                              "Leaving it alone", name);
                 return;
@@ -1284,6 +1316,11 @@ void pa_discover_add_source_output(struct userdata *u, pa_source_output *sout)
             return;
         }
 
+        if (node->rsetid)
+            pa_murphyif_add_node(u, node);
+        else if (resdef)
+            pa_murphyif_create_resource_set(u, node, resdef);
+
         pa_discover_add_node_to_ptr_hash(u, sout, node);
     }
 
@@ -2151,23 +2188,14 @@ static pa_source *make_input_prerouting(struct userdata *u,
 
 static mir_node_type get_stream_routing_class(pa_proplist *pl)
 {
-    const char    *clid;
-    mir_node_type  type;
-    char          *e;
+    mir_node_type t;
 
     pa_assert(pl);
 
-    if ((clid = pa_proplist_gets(pl, PA_PROP_ROUTING_CLASS_ID))) {
-        type = strtol(clid, &e, 10);
+    t = pa_utils_get_stream_class(pl);
 
-        if (!*e) {
-            if (type >= mir_application_class_begin &&
-                type <  mir_application_class_end)
-            {
-                return type;
-            }
-        }
-    }
+    if (t >= mir_application_class_begin && t <  mir_application_class_end)
+        return t;
 
     return mir_node_type_unknown;
 }
index 1bdfe2c..b084d8f 100644 (file)
@@ -167,6 +167,7 @@ pa_bool_t pa_mir_config_parse_file(struct userdata *u, const char *path)
     pa_module *module;
     pa_mir_config *config;
     int success;
+    char buf[4096];
 
     pa_assert(u);
     pa_assert_se((module = u->module));
@@ -184,6 +185,9 @@ pa_bool_t pa_mir_config_parse_file(struct userdata *u, const char *path)
         success = use_default_configuration(u);
     }
 
+    pa_nodeset_print_maps(u, buf, sizeof(buf));
+    pa_log_debug(buf);
+
     return success;
 }
 
@@ -203,10 +207,10 @@ static pa_bool_t use_default_configuration(struct userdata *u)
         mir_router_assign_class_to_rtgroup(u, c->class, c->type, c->rtgroup);
 
     for (t = rolemap; t->id; t++)
-        pa_nodeset_add_role(u, t->id, t->type);
+        pa_nodeset_add_role(u, t->id, t->type, NULL);
 
     for (t = binmap; t->id; t++)
-        pa_nodeset_add_binary(u, t->id, t->type);
+        pa_nodeset_add_binary(u, t->id, t->type, NULL);
 
     for (p = priormap;  p->class;  p++)
         mir_router_assign_class_priority(u, p->class, p->priority);
index 65ed0d5..3f936a6 100644 (file)
@@ -26,7 +26,7 @@ application_class {
     route = {
         output = routing_group.default_output
     },
-    roles = { "event" },
+    roles = { event = no_resource }
 }
 
 application_class {
@@ -37,7 +37,7 @@ application_class {
         input = routing_group.phone_input,
         output = routing_group.phone_output
     },
-    roles = { "phone", "carkit" },
+    roles = { phone = no_resource, carkit = no_resource }
 }
 
 application_class {
@@ -46,7 +46,7 @@ application_class {
     route = {
         output = routing_group.default_output
     },
-    roles = { "ringtone", "alarm" },
+    roles = { ringtone = no_resource, alarm = no_resource }
 }
 
 application_class {
@@ -56,8 +56,7 @@ application_class {
     route = {
         output = routing_group.default_output
     },
-    roles = { "navigator" },
-    needs = { "resource" }
+    roles = { navigator = {0, "autorelease", "mandatory", "shared"} }
 }
 
 application_class {
@@ -67,8 +66,7 @@ application_class {
     route = {
         output = routing_group.default_output
     },
-    roles = { "game" },
-    needs = { "resource" }
+    roles = { game = {0, "mandatory", "exclusive"} }
 }
 
 application_class {
@@ -78,8 +76,7 @@ application_class {
     route = {
         output = routing_group.default_output
     },
-    roles = { "radio" },
-    needs = { "resource" }
+    roles = { radio = {1, "mandatory", "exclusive"} },
 }
 
 application_class {
@@ -89,8 +86,10 @@ application_class {
     route = {
         output = routing_group.default_output
     },
-    roles = { "music", "video", "test" },
-    needs = { "resource" }
+    roles = { music = {1, "mandatory", "exclusive"},
+              video = {1, "mandatory", "exclusive"},
+             test  = {0, "mandatory", "exclusive"}
+    }
 }
 
 application_class {
@@ -100,8 +99,10 @@ application_class {
     route = {
         output = routing_group.default_output
     },
-    roles = { "animation" },
-    binaries = { "firefox", "chrome" }
+    roles = { animation = {0, "mandatory", "shared"} },
+    binaries = { firefox = {0, "mandatory","exclusive"},
+                 chrome  = {0, "mandatory", "exclusive"}
+    }
 }
 
 audio_resource {
index 8353ac4..cd90c3e 100644 (file)
@@ -168,7 +168,7 @@ static mrp_msg_t *resource_create_request(uint32_t, mrp_resproto_request_t);
 static pa_bool_t  resource_send_message(resource_interface *, mrp_msg_t *,
                                         uint32_t, uint16_t, uint32_t);
 static pa_bool_t  resource_set_create_node(struct userdata *, mir_node *,
-                                           pa_bool_t);
+                                           pa_nodeset_resdef *, pa_bool_t);
 static pa_bool_t  resource_set_create_all(struct userdata *);
 static pa_bool_t  resource_set_destroy_node(struct userdata *, uint32_t);
 static pa_bool_t  resource_set_destroy_all(struct userdata *);
@@ -526,7 +526,9 @@ void pa_murphyif_add_audio_attribute(struct userdata *u,
 #endif
 }
 
-void pa_murphyif_create_resource_set(struct userdata *u, mir_node *node)
+void pa_murphyif_create_resource_set(struct userdata *u,
+                                     mir_node *node,
+                                     pa_nodeset_resdef *resdef)
 {
     pa_core *core;
     pa_murphyif *murphyif;
@@ -556,7 +558,7 @@ void pa_murphyif_create_resource_set(struct userdata *u, mir_node *node)
         break;
 
     case CONNECTED:
-        node->localrset = resource_set_create_node(u, node, TRUE);
+        node->localrset = resource_set_create_node(u, node, resdef, TRUE);
         break;
 
     case DISCONNECTED:
@@ -889,11 +891,9 @@ static pa_bool_t resource_send_message(resource_interface *rif,
 
 static pa_bool_t resource_set_create_node(struct userdata *u,
                                           mir_node *node,
+                                          pa_nodeset_resdef *resdef,
                                           pa_bool_t acquire)
 {
-    static uint32_t rset_flags = RESPROTO_RSETFLAG_NOEVENTS    |
-                                 RESPROTO_RSETFLAG_AUTOACQUIRE ;
-
     pa_core *core;
     pa_murphyif *murphyif;
     resource_interface *rif;
@@ -901,13 +901,14 @@ static pa_bool_t resource_set_create_node(struct userdata *u,
     mrp_msg_t *msg;
     uint16_t reqid;
     uint32_t seqno;
+    uint32_t rset_flags;
     const char *class;
     pa_sink_input *sinp;
     pa_source_output *sout;
     audio_resource_t *res;
     const char *resnam;
     uint32_t audio_flags = 0;
-    uint32_t priority = 0;
+    uint32_t priority;
     pa_proplist *proplist = NULL;
     pa_bool_t success = TRUE;
 
@@ -940,6 +941,14 @@ static pa_bool_t resource_set_create_node(struct userdata *u,
 
     pa_assert_se((resnam = res->name));
 
+    rset_flags = RESPROTO_RSETFLAG_NOEVENTS;
+    rset_flags |= (acquire ? RESPROTO_RSETFLAG_AUTOACQUIRE : 0);
+    rset_flags |= (resdef ? resdef->flags.rset : 0);
+
+    audio_flags = (resdef ? resdef->flags.audio : 0);
+
+    priority = (resdef ? resdef->priority : 0);
+
     msg = resource_create_request(seqno, reqid);
 
     if (PUSH_VALUE(msg,   RESOURCE_FLAGS   , UINT32, rset_flags)  &&
@@ -982,7 +991,7 @@ static pa_bool_t resource_set_create_all(struct userdata *u)
 
     while ((node = pa_nodeset_iterate_nodes(u, &idx))) {
         if (node->implement == mir_stream && !node->rsetid) {
-            node->localrset = resource_set_create_node(u, node, FALSE);
+            node->localrset = resource_set_create_node(u, node, NULL, FALSE);
             success &= node->localrset;
         }
     }
index 39fdef9..983bfde 100644 (file)
@@ -30,6 +30,7 @@ typedef void mrp_domctl_value_t;
 
 #include "userdata.h"
 
+
 typedef void (*pa_murphyif_watch_cb)(struct userdata *u, const char *,
                                          int, mrp_domctl_value_t **);
 
@@ -46,7 +47,8 @@ void pa_murphyif_add_audio_resource(struct userdata *, mir_direction,
                                     const char *);
 void pa_murphyif_add_audio_attribute(struct userdata *, const char *,
                                      const char *, mqi_data_type_t, ... );
-void pa_murphyif_create_resource_set(struct userdata *, mir_node *);
+void pa_murphyif_create_resource_set(struct userdata *, mir_node *,
+                                     pa_nodeset_resdef *);
 void pa_murphyif_destroy_resource_set(struct userdata *, mir_node *);
 
 int pa_murphyif_add_node(struct userdata *, mir_node *);
index cffc755..0534c3d 100644 (file)
 #define APCLASS_DIM  (mir_application_class_end - mir_application_class_begin)
 
 struct pa_nodeset {
-    pa_idxset  *nodes;
-    pa_hashmap *roles;
-    pa_hashmap *binaries;
-    const char *class_name[APCLASS_DIM];
-    pa_bool_t   need_resource[APCLASS_DIM];
+    pa_idxset      *nodes;
+    pa_hashmap     *roles;
+    pa_hashmap     *binaries;
+    const char     *class_name[APCLASS_DIM];
 };
 
 
+static void free_map_cb(void *, void *);
+static int print_map(pa_hashmap *, const char *, char *, int);
+
 pa_nodeset *pa_nodeset_init(struct userdata *u)
 {
     pa_nodeset *ns;
@@ -67,8 +69,8 @@ void pa_nodeset_done(struct userdata *u)
 
     if (u && (ns = u->nodeset)) {
         pa_idxset_free(ns->nodes, NULL, NULL);
-        pa_hashmap_free(ns->roles, NULL, NULL);
-        pa_hashmap_free(ns->binaries, NULL, NULL);
+        pa_hashmap_free(ns->roles, free_map_cb, u);
+        pa_hashmap_free(ns->binaries, free_map_cb, u);
 
         for (i = 0;  i < APCLASS_DIM;  i++)
             pa_xfree((void *)ns->class_name[i]);
@@ -122,104 +124,141 @@ const char *pa_nodeset_get_class(struct userdata *u, mir_node_type t)
     return NULL;
 }
 
-int pa_nodeset_add_role(struct userdata *u, const char *role, mir_node_type t)
+int pa_nodeset_add_role(struct userdata *u,
+                        const char *role,
+                        mir_node_type type,
+                        pa_nodeset_resdef *resdef)
 {
     pa_nodeset *ns;
-    void *value = NULL + t;
+    pa_nodeset_map *map;
 
     pa_assert(u);
     pa_assert(role);
-    pa_assert(t >= mir_application_class_begin &&
-              t <  mir_application_class_end);
+    pa_assert(type >= mir_application_class_begin &&
+              type <  mir_application_class_end);
     pa_assert_se((ns = u->nodeset));
 
-    return pa_hashmap_put(ns->roles, role, value);
+    map = pa_xnew0(pa_nodeset_map, 1);
+    map->name = pa_xstrdup(role);
+    map->type = type;
+
+    if (resdef) {
+        map->resdef = pa_xnew(pa_nodeset_resdef, 1);
+        memcpy(map->resdef, resdef, sizeof(pa_nodeset_resdef));
+    }
+
+    return pa_hashmap_put(ns->roles, map->name, map);
 }
 
 void pa_nodeset_delete_role(struct userdata *u, const char *role)
 {
+    pa_nodeset_map *map;
     pa_nodeset *ns;
 
     pa_assert(u);
     pa_assert(role);
     pa_assert_se((ns = u->nodeset));
 
-    pa_hashmap_remove(ns->roles, role);
+    if ((map = pa_hashmap_remove(ns->roles, role))) {
+        pa_xfree((void *)map->name);
+        pa_xfree((void *)map->resdef);
+    }
 }
 
-mir_node_type pa_nodeset_get_type_by_role(struct userdata *u, const char *role)
+pa_nodeset_map *pa_nodeset_get_map_by_role(struct userdata *u,
+                                           const char *role)
 {
+    pa_nodeset_map *map;
     pa_nodeset *ns;
-    mir_node_type t;
 
     pa_assert(u);
     pa_assert_se((ns = u->nodeset));
 
-    if (role) {
-        t = pa_hashmap_get(ns->roles, role) - NULL;
-
-        if (t >= mir_application_class_begin && t < mir_application_class_end)
-            return t;
-    }
+    if (role)
+        map = pa_hashmap_get(ns->roles, role);
+    else
+        map = NULL;
+        
 
-    return mir_node_type_unknown;
+    return map;
 }
 
-int pa_nodeset_add_binary(struct userdata *u, const char *bin, mir_node_type t)
+int pa_nodeset_add_binary(struct userdata *u,
+                          const char *bin,
+                          mir_node_type type,
+                          pa_nodeset_resdef *resdef)
 {
     pa_nodeset *ns;
-    void *value = NULL + t;
+    pa_nodeset_map *map;
 
     pa_assert(u);
     pa_assert(bin);
-    pa_assert(t >= mir_application_class_begin &&
-              t <  mir_application_class_end);
+    pa_assert(type >= mir_application_class_begin &&
+              type <  mir_application_class_end);
     pa_assert_se((ns = u->nodeset));
 
-    return pa_hashmap_put(ns->binaries, bin, value);
+    map = pa_xnew0(pa_nodeset_map, 1);
+    map->name = pa_xstrdup(bin);
+    map->type = type;
+
+    if (resdef) {
+        map->resdef = pa_xnew(pa_nodeset_resdef, 1);
+        memcpy(map->resdef, resdef, sizeof(pa_nodeset_resdef));
+    }
+
+    return pa_hashmap_put(ns->binaries, map->name, map);
 }
 
 void pa_nodeset_delete_binary(struct userdata *u, const char *bin)
 {
+    pa_nodeset_map *map;
     pa_nodeset *ns;
 
     pa_assert(u);
     pa_assert(bin);
     pa_assert_se((ns = u->nodeset));
 
-    pa_hashmap_remove(ns->binaries, bin);
+    if ((map = pa_hashmap_remove(ns->binaries, bin))) {
+        pa_xfree((void *)map->name);
+        pa_xfree((void *)map->resdef);
+    }
 }
 
-mir_node_type pa_nodeset_get_type_by_binary(struct userdata *u,const char *bin)
+pa_nodeset_map *pa_nodeset_get_map_by_binary(struct userdata *u,
+                                             const char *bin)
 {
+    pa_nodeset_map *map;
     pa_nodeset *ns;
-    mir_node_type t;
 
     pa_assert(u);
     pa_assert_se((ns = u->nodeset));
 
-    if (bin) {
-        t = pa_hashmap_get(ns->binaries, bin) - NULL;
-
-        if (t >= mir_application_class_begin && t < mir_application_class_end)
-            return t;
-    }
+    if (bin)
+        map = pa_hashmap_get(ns->binaries, bin);
+    else
+        map = NULL;
+        
 
-    return mir_node_type_unknown;
+    return map;
 }
 
-void pa_nodeset_need_resource(struct userdata *u, mir_node_type t)
+int pa_nodeset_print_maps(struct userdata *u, char *buf, int len)
 {
     pa_nodeset *ns;
-    int ac;
+    char *p, *e;
 
     pa_assert(u);
+    pa_assert(buf);
+    pa_assert(len > 0);
+
     pa_assert_se((ns = u->nodeset));
 
-    if (t >= mir_application_class_begin && t < mir_application_class_end) {
-        ac = t - mir_application_class_begin;
-        ns->need_resource[ac] = TRUE;
-    }    
+    e = (p = buf) + len;
+
+    p += print_map(ns->roles, "roles", p, e-p);
+    p += print_map(ns->binaries, "binaries", p, e-p);
+
+    return p - buf;
 }
 
 mir_node *pa_nodeset_iterate_nodes(struct userdata *u, uint32_t *pidx)
@@ -290,12 +329,6 @@ mir_node *mir_node_create(struct userdata *u, mir_node *data)
 
     mir_router_register_node(u, node);
     
-    if (node->implement == mir_stream) {
-        if (!node->rsetid && mir_node_need_resource(u, node->type))
-            pa_murphyif_create_resource_set(u, node);
-        else
-            pa_murphyif_add_node(u, node);
-    }
 
     return node;
 }
@@ -309,15 +342,10 @@ void mir_node_destroy(struct userdata *u, mir_node *node)
 
     if (node) {
         if (node->implement == mir_stream) {
-            if (node->type >= mir_application_class_begin &&
-                node->type <  mir_application_class_end   &&
-                ns->need_resource[node->type])
-            {
+            if (node->localrset)
                 pa_murphyif_destroy_resource_set(u, node);
-            }
-            else {
+            else
                 pa_murphyif_delete_node(u, node);
-            }
         }
 
         mir_router_unregister_node(u, node);
@@ -351,20 +379,6 @@ mir_node *mir_node_find_by_index(struct userdata *u, uint32_t nodidx)
     return node;
 }
 
-pa_bool_t mir_node_need_resource(struct userdata *u, mir_node_type type)
-{
-    pa_nodeset *ns;
-
-    pa_assert(u);
-    pa_assert_se((ns = u->nodeset));
-    pa_assert(ns->need_resource);
-
-    if (type <  mir_application_class_begin ||
-        type >= mir_application_class_end     )
-        return FALSE;
-
-    return ns->need_resource[type];
-}
 
 int mir_node_print(mir_node *node, char *buf, int len)
 {
@@ -491,6 +505,51 @@ const char *mir_privacy_str(mir_privacy privacy)
     }
 }
 
+
+static void free_map_cb(void *void_map, void *void_userdata)
+{
+    struct userdata *u   = (struct userdata *)void_userdata;
+    pa_nodeset_map  *map = (pa_nodeset_map *)void_map;
+
+    pa_xfree((void *)map->name);
+    pa_xfree((void *)map->resdef);
+
+    pa_xfree(map);
+}
+
+static int print_map(pa_hashmap *map, const char *name, char *buf, int len)
+{
+#define PRINT(fmt,args...) \
+    do { if (p < e) p += snprintf(p, e-p, fmt "\n", args); } while (0)
+
+    pa_nodeset_map *m;
+    pa_nodeset_resdef *r;
+    const char *type;
+    void *state;
+    char *p, *e;
+
+    e = (p = buf) + len;
+
+    if (buf && len > 0) {
+        PRINT("%s mappings:", name);
+
+        PA_HASHMAP_FOREACH(m, map, state) {
+            type = mir_node_type_str(m->type);
+
+            if (!(r = m->resdef))
+                PRINT("    %-15s => %-10s", m->name, type);
+            else {
+                PRINT("    %-15s => %-10s resource: priority %u, flags rset "
+                      "0x%x, audio 0x%x", m->name, type, r->priority,
+                      r->flags.rset, r->flags.audio);
+            }
+        }
+    }
+    
+    return p - buf;
+
+#undef PRINT
+}
                                   
 /*
  * Local Variables:
index c955169..efed7c0 100644 (file)
@@ -96,6 +96,20 @@ enum mir_privacy {
     mir_private
 };
 
+struct pa_nodeset_resdef {
+    uint32_t           priority;
+    struct {
+        uint32_t rset;
+        uint32_t audio;
+    }                  flags;
+};
+
+struct pa_nodeset_map {
+    const char        *name;
+    mir_node_type      type;
+    pa_nodeset_resdef *resdef;
+}; 
+
 struct pa_node_card {
     uint32_t  index;
     char     *profile;
@@ -154,15 +168,17 @@ int pa_nodeset_add_class(struct userdata *u, mir_node_type , const char *);
 void pa_nodeset_delete_class(struct userdata *, mir_node_type);
 const char *pa_nodeset_get_class(struct userdata *, mir_node_type);
 
-int pa_nodeset_add_role(struct userdata *, const char *, mir_node_type);
+int pa_nodeset_add_role(struct userdata *, const char *, mir_node_type,
+                        pa_nodeset_resdef *);
 void pa_nodeset_delete_role(struct userdata *, const char *);
-mir_node_type pa_nodeset_get_type_by_role(struct userdata *, const char *);
+pa_nodeset_map *pa_nodeset_get_map_by_role(struct userdata *, const char *);
 
-int pa_nodeset_add_binary(struct userdata *, const char *, mir_node_type);
+int pa_nodeset_add_binary(struct userdata *, const char *, mir_node_type,
+                        pa_nodeset_resdef *);
 void pa_nodeset_delete_binary(struct userdata *, const char *);
-mir_node_type pa_nodeset_get_type_by_binary(struct userdata *, const char *);
+pa_nodeset_map *pa_nodeset_get_map_by_binary(struct userdata *, const char *);
 
-void pa_nodeset_need_resource(struct userdata *, mir_node_type);
+int pa_nodeset_print_maps(struct userdata *, char *, int);
 
 mir_node *pa_nodeset_iterate_nodes(struct userdata *, uint32_t *);
 
@@ -172,7 +188,6 @@ void mir_node_destroy(struct userdata *, mir_node *);
 
 mir_node *mir_node_find_by_index(struct userdata *, uint32_t);
 
-pa_bool_t mir_node_need_resource(struct userdata *, mir_node_type);
 
 int mir_node_print(mir_node *, char *, int);
 
index 3ea0b6c..c072cb6 100644 (file)
@@ -24,6 +24,7 @@
 #include <errno.h>
 
 #include <pulsecore/pulsecore-config.h>
+#include <pulsecore/core-util.h>
 
 #include <murphy/common/macros.h>
 #include <murphy/core/lua-utils/object.h>
@@ -32,6 +33,7 @@
 #include <murphy/core/lua-utils/funcbridge.h>
 #include <murphy/domain-control/client.h>
 #include <murphy/resource/data-types.h>
+#include <murphy/resource/protocol.h>
 
 #include "scripting.h"
 #include "node.h"
@@ -117,6 +119,12 @@ typedef struct {
     const char         *output;
 } route_t;
 
+typedef struct {
+    const char         *name;
+    pa_bool_t           needres;
+    pa_nodeset_resdef   resource;
+} map_t;
+
 struct scripting_apclass {
     struct userdata    *userdata;
     const char         *name;
@@ -124,8 +132,8 @@ struct scripting_apclass {
     mir_node_type       type;
     int                 priority;
     route_t            *route;
-    mrp_lua_strarray_t *roles;
-    mrp_lua_strarray_t *binaries;
+    map_t              *roles;
+    map_t              *binaries;
     struct {
         pa_bool_t resource;
     }                   needs;
@@ -176,7 +184,6 @@ typedef enum {
     CLASS,
     INPUT,
     LIMIT,
-    NEEDS,
     ROUTE,
     ROLES,
     TABLE,
@@ -199,6 +206,7 @@ typedef enum {
     IMPLEMENT,
     NODE_TYPE,
     ATTRIBUTES,
+    AUTORELEASE,
     DESCRIPTION,
 } field_t;
 
@@ -293,6 +301,10 @@ static void resource_names_destroy(resource_name_t *);
 static attribute_t *attributes_check(lua_State *, int);
 static void attributes_destroy(attribute_t *);
 
+static map_t *map_check(lua_State *, int);
+static int map_push(lua_State *, map_t *);
+static void map_destroy(map_t *);
+
 static field_t field_check(lua_State *, int, const char **);
 static field_t field_name_to_type(const char *, size_t);
 static int make_id(char *buf, size_t len, const char *fmt, ...);
@@ -1552,13 +1564,11 @@ static int apclass_create(lua_State *L)
     mir_node_type type = -1;
     int priority = -1;
     route_t *route = NULL;
-    mrp_lua_strarray_t *roles = NULL;
-    mrp_lua_strarray_t *binaries = NULL;
-    mrp_lua_strarray_t *needs = NULL;
+    map_t *roles = NULL;
+    map_t *binaries = NULL;
     pa_bool_t needs_resource = FALSE;
-    const char *role;
-    const char *binary;
-    const char *need;
+    pa_nodeset_resdef *resdef;
+    map_t *r, *b;
     size_t i;
     pa_bool_t ir, or;
 
@@ -1577,27 +1587,13 @@ static int apclass_create(lua_State *L)
         case NODE_TYPE:   type = luaL_checkint(L, -1);                 break;
         case PRIORITY:    priority = luaL_checkint(L, -1);             break;
         case ROUTE:       route = route_check(L, -1);                  break;
-        case ROLES:       roles = mrp_lua_check_strarray(L, -1);       break;
-        case BINARIES:    binaries = mrp_lua_check_strarray(L, -1);    break;
-        case NEEDS:       needs = mrp_lua_check_strarray(L, -1);       break;
+        case ROLES:       roles = map_check(L, -1);                    break;
+        case BINARIES:    binaries = map_check(L, -1);                 break;
         default:          luaL_error(L, "bad field '%s'", fldnam);     break;
         }
 
     } /* MRP_LUA_FOREACH_FIELD */
 
-    if (needs) {
-        for (i = 0;   i < needs->nstring;   i++) {
-            need = needs->strings[i];
-
-            if (!strcmp(need, "resource"))
-                needs_resource = TRUE;
-            else
-                luaL_error(L, "invalid need '%s'", need);
-        }
-    }
-
-    if (needs_resource && !class)
-        luaL_error(L, "missing or invalid class field");
     if (type < mir_application_class_begin ||
         type >= mir_application_class_end    )
         luaL_error(L, "missing or invalid node_type %d", type);
@@ -1605,6 +1601,8 @@ static int apclass_create(lua_State *L)
         luaL_error(L, "missing or invalid priority field");
     if (!route)
         luaL_error(L, "missing or invalid route field");
+    if (!roles && !binaries)
+        luaL_error(L, "missing roles or binaries");
 
     make_id(name, sizeof(name), "%s", mir_node_type_str(type));
 
@@ -1641,30 +1639,27 @@ static int apclass_create(lua_State *L)
     }
 
     if (roles) {
-        for (i = 0;  i < roles->nstring;  i++) {
-            role = roles->strings[i];
+        for (r = roles;  r->name;  r++) {
+            resdef = r->needres ? &r->resource : NULL;
 
-            if (pa_nodeset_add_role(u, role, type)) {
+            if (pa_nodeset_add_role(u, r->name, type, resdef)) {
                 luaL_error(L, "role '%s' is added to mutiple application "
-                           "classes", role);
+                           "classes", r->name);
             }
         }
     }
 
     if (binaries) {
-        for (i = 0;  i < binaries->nstring;  i++) {
-            binary = binaries->strings[i];
+        for (b = binaries;  b->name;  b++) {
+            resdef = b->needres ? &b->resource : NULL;
 
-            if (pa_nodeset_add_binary(u, binary, type)) {
+            if (pa_nodeset_add_binary(u, b->name, type, resdef)) {
                 luaL_error(L, "binary '%s' is added to multiple application "
-                           "classes", binary);
+                           "classes", b->name);
             }
         }
     }
 
-    if (needs_resource)
-        pa_nodeset_need_resource(u, type);
-
     MRP_LUA_LEAVE(1);
 }
 
@@ -1682,13 +1677,13 @@ static int apclass_getfield(lua_State *L)
         lua_pushnil(L);
     else {
         switch (fld) {
-        case NAME:           lua_pushstring(L, ac->name);              break;
-        case NODE_TYPE:      lua_pushinteger(L, ac->type);             break;
-        case PRIORITY:       lua_pushinteger(L, ac->priority);         break;
-        case ROUTE:          route_push(L, ac->route);                 break;
-        case ROLES:          mrp_lua_push_strarray(L, ac->roles);      break;
-        case BINARIES:       mrp_lua_push_strarray(L, ac->binaries);   break;
-        default:             lua_pushnil(L);                           break;
+        case NAME:           lua_pushstring(L, ac->name);          break;
+        case NODE_TYPE:      lua_pushinteger(L, ac->type);         break;
+        case PRIORITY:       lua_pushinteger(L, ac->priority);     break;
+        case ROUTE:          route_push(L, ac->route);             break;
+        case ROLES:          map_push(L, ac->roles);               break;
+        case BINARIES:       map_push(L, ac->binaries);            break;
+        default:             lua_pushnil(L);                       break;
         }
     }
 
@@ -1724,8 +1719,7 @@ static void apclass_destroy(void *data)
 {
     scripting_apclass *ac = (scripting_apclass *)data;
     struct userdata *u;
-    mrp_lua_strarray_t *roles;
-    mrp_lua_strarray_t *binaries;
+    map_t *r, *b;
     size_t i;
 
     MRP_LUA_ENTER;
@@ -1743,19 +1737,19 @@ static void apclass_destroy(void *data)
     pa_xfree((void *)ac->class);
     ac->class = NULL;
 
-    if ((roles = ac->roles)) {
-        for (i = 0;   i < roles->nstring;  i++)
-            pa_nodeset_delete_role(u, roles->strings[i]);
+    if (ac->roles) {
+        for (r = ac->roles;  r->name;  r++)
+            pa_nodeset_delete_role(u, r->name);
 
-        mrp_lua_free_strarray(ac->roles);
+        map_destroy(ac->roles);
         ac->roles = NULL;
     }
 
-    if ((binaries = ac->binaries)) {
-        for (i = 0;   i < binaries->nstring;  i++)
-            pa_nodeset_delete_binary(u, binaries->strings[i]);
+    if (ac->binaries) {
+        for (b = ac->binaries;  b->name;  b++)
+            pa_nodeset_delete_binary(u, b->name);
 
-        mrp_lua_free_strarray(ac->binaries);
+        map_destroy(ac->binaries);
         ac->binaries = NULL;
     }
 
@@ -2399,6 +2393,137 @@ static void attributes_destroy(attribute_t *attrs)
     }
 }
 
+static map_t *map_check(lua_State *L, int tbl)
+{
+    int def;
+    size_t namlen;
+    const char *name;
+    const char *flag;
+    map_t *m, *map = NULL;
+    size_t n = 0;
+    size_t i, len;
+    int priority;
+    pa_nodeset_resdef *rd;
+
+    tbl = (tbl < 0) ? lua_gettop(L) + tbl + 1 : tbl;
+
+    luaL_checktype(L, tbl, LUA_TTABLE);
+
+    MRP_LUA_FOREACH_FIELD(L, tbl, name, namlen) {
+        if (!name[0])
+            luaL_error(L, "invalid role or binary definition");
+
+        map = pa_xrealloc(map, sizeof(map_t) * (n + 2));
+        memset(map + n, 0, sizeof(map_t) * 2);
+
+        m = map + n++;
+        def = lua_gettop(L);
+
+        m->name = pa_xstrdup(name);
+
+        switch (lua_type(L, -1)) {
+
+        case LUA_TNUMBER:
+            m->needres = FALSE;
+            break;
+
+        case LUA_TTABLE:
+            m->needres = TRUE;
+
+            if ((len = luaL_getn(L, def)) < 1)
+                luaL_error(L, "invalid resource definition '%s'", name);
+
+            for (i = 1;  i <= len;  i++) {
+                lua_pushnumber(L, (int)i);
+                lua_gettable(L, def);
+
+                if (i == 1) {
+                    priority = luaL_checkint(L, -1);
+
+                    if (priority < 0 || priority > 7) {
+                        luaL_error(L, "invalid priority %d for '%s'",
+                                   priority, name);
+                    }
+
+                    m->resource.priority = priority;
+                }
+                else {
+                    flag = luaL_checkstring(L, -1);
+                    rd = &m->resource;
+
+                    if (pa_streq(flag, "autorelease"))
+                        rd->flags.rset |= RESPROTO_RSETFLAG_AUTORELEASE;
+                    else if (pa_streq(flag, "mandatory"))
+                        rd->flags.audio |= RESPROTO_RESFLAG_MANDATORY;
+                    else if (pa_streq(flag, "shared"))
+                        rd->flags.audio |= RESPROTO_RESFLAG_SHARED;
+                    else if (!pa_streq(flag, "optional") &&
+                             !pa_streq(flag, "exclusive") )
+                    {
+                        luaL_error(L, "invalid flag '%s' for '%s'", flag,name);
+                    }
+                }
+
+                lua_pop(L, 1);
+            }
+
+            break;
+
+        default:
+            luaL_error(L, "invalid resource specification. "
+                       "Should be either 'no_resource' or a table");
+            break;
+        }
+    } /* FOREACH_FIELD */
+
+    return map;
+}
+
+static int map_push(lua_State *L, map_t *map)
+{
+    map_t *m;
+
+    if (!map)
+        lua_pushnil(L);
+    else {
+        lua_newtable(L);
+
+        for (m = map;  m->name;  m++) {
+            if (!m->needres)
+                lua_pushnumber(L, 0);
+            else {
+                lua_newtable(L);
+                lua_pushinteger(L, m->resource.priority);
+                if (m->resource.flags.rset & RESPROTO_RSETFLAG_AUTORELEASE)
+                    lua_pushstring(L, "autorelease");
+                if (m->resource.flags.audio & RESPROTO_RESFLAG_MANDATORY)
+                    lua_pushstring(L, "mandatory");
+                else
+                    lua_pushstring(L, "optional");
+                if (m->resource.flags.audio & RESPROTO_RESFLAG_SHARED)
+                    lua_pushstring(L, "shared");
+                else
+                    lua_pushstring(L, "exclusive");
+            }
+            lua_setfield(L, -2, m->name);
+        }
+    }
+
+    return 1;
+}
+
+static void map_destroy(map_t *map)
+{
+    map_t *m;
+
+    if (map) {
+        for (m = map;  m->name;  m++) {
+            pa_xfree((void *)m->name);
+        }
+        pa_xfree(map);
+    }
+}
+
 
 static field_t field_check(lua_State *L, int idx, const char **ret_fldnam)
 {
@@ -2454,10 +2579,6 @@ static field_t field_name_to_type(const char *name, size_t len)
             if (!strcmp(name, "limit"))
                 return LIMIT;
             break;
-        case 'n':
-            if (!strcmp(name, "needs"))
-                return NEEDS;
-            break;
         case 'r':
             if (!strcmp(name, "route"))
                 return ROUTE;
@@ -2575,6 +2696,8 @@ static field_t field_name_to_type(const char *name, size_t len)
         break;        
 
     case 11:
+        if (!strcmp(name, "autorelease"))
+            return AUTORELEASE;
         if (!strcmp(name, "description"))
             return DESCRIPTION;
         break;        
@@ -2781,6 +2904,8 @@ static bool define_constants(lua_State *L)
         lua_pop(L, 1);
     }
 
+    lua_pushnumber(L, 0);
+    lua_setglobal(L, "no_resource");
 
     return success;
 }
index 717f357..ae59994 100644 (file)
@@ -33,9 +33,9 @@ static void sink_input_block(pa_sink_input *, pa_bool_t);
 
 pa_bool_t pa_stream_state_start_corked(struct userdata *u,
                                        pa_sink_input_new_data *data,
-                                       mir_node_type type)
+                                       pa_nodeset_resdef *resdef)
 {
-    if (mir_node_need_resource(u, type)) {
+    if (resdef) {
         data->flags |= PA_SINK_INPUT_START_CORKED;
         return TRUE;
     }
index d885a01..7e9e713 100644 (file)
@@ -31,7 +31,7 @@
 
 pa_bool_t pa_stream_state_start_corked(struct userdata *,
                                        pa_sink_input_new_data *,
-                                       mir_node_type);
+                                       pa_nodeset_resdef *);
 void pa_stream_state_change(struct userdata *u, mir_node *, int);
 
 
index 2b6a3a2..51d7623 100644 (file)
@@ -41,6 +41,9 @@
 #define PA_PROP_NODE_TYPE              "node.type"
 #define PA_PROP_NODE_ROLE              "node.role"
 #define PA_PROP_RESOURCE_SET_ID        "resource.set.id"
+#define PA_PROP_RESOURCE_PRIORITY      "resource.set.priority"
+#define PA_PROP_RESOURCE_SET_FLAGS     "resource.set.flags"
+#define PA_PROP_RESOURCE_AUDIO_FLAGS   "resource.audio.flags"
 
 #define PA_ZONE_NAME_DEFAULT           "driver"
 
@@ -61,6 +64,8 @@ typedef struct pa_scripting             pa_scripting;
 typedef struct pa_mir_volume            pa_mir_volume;
 typedef struct pa_mir_config            pa_mir_config;
 typedef struct pa_nodeset               pa_nodeset;
+typedef struct pa_nodeset_resdef        pa_nodeset_resdef;
+typedef struct pa_nodeset_map           pa_nodeset_map;
 typedef struct pa_node_card             pa_node_card;
 typedef struct pa_card_hooks            pa_card_hooks;
 typedef struct pa_port_hooks            pa_port_hooks;
index c613a22..e883ce1 100644 (file)
@@ -56,6 +56,7 @@ struct pa_null_sink {
 static uint32_t stamp;
 
 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)
@@ -309,6 +310,97 @@ int pa_utils_get_stream_class(pa_proplist *pl)
     return (int)clid;
 }
 
+
+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)
 {
     char nodeidx[256];
@@ -468,7 +560,6 @@ uint32_t pa_utils_get_stamp(void)
 
 
 
-
 /*
  * Local Variables:
  * c-basic-offset: 4
index 44ad0f1..87b076a 100644 (file)
@@ -47,7 +47,13 @@ void      pa_utils_set_stream_routing_method_property(pa_proplist *,pa_bool_t);
 pa_bool_t pa_utils_stream_has_default_route(pa_proplist *);
 int       pa_utils_get_stream_class(pa_proplist *);
 
+
 #ifdef foomurphyuserdatafoo  /* argh ... */
+pa_bool_t pa_utils_set_resource_properties(pa_proplist *, pa_nodeset_resdef *);
+pa_bool_t pa_utils_unset_resource_properties(pa_proplist *);
+pa_nodeset_resdef *pa_utils_get_resource_properties(pa_proplist *,
+                                                    pa_nodeset_resdef *);
+
 void      pa_utils_set_port_properties(pa_device_port *, mir_node *);
 mir_node *pa_utils_get_node_from_port(struct userdata *, pa_device_port *);
 mir_node *pa_utils_get_node_from_stream(struct userdata *,mir_direction,void*);