diff --git a/modules/module-lua-scripting/api.c b/modules/module-lua-scripting/api.c index 4564a0a8791e0a3968773127f325de80533f3690..40bf4049b148e8b68325ceb719ff5fc918fcf6c3 100644 --- a/modules/module-lua-scripting/api.c +++ b/modules/module-lua-scripting/api.c @@ -106,6 +106,36 @@ push_wpiterator (lua_State *L, WpIterator *it) return 2; } +/* Metadata WpIterator */ + +static int +metadata_iterator_next (lua_State *L) +{ + WpIterator *it = wplua_checkboxed (L, 1, WP_TYPE_ITERATOR); + GValue item = G_VALUE_INIT; + if (wp_iterator_next (it, &item)) { + guint32 s = 0; + const gchar *k = NULL, *t = NULL, *v = NULL; + wp_metadata_iterator_item_extract (&item, &s, &k, &t, &v); + lua_pushinteger (L, s); + lua_pushstring (L, k); + lua_pushstring (L, t); + lua_pushstring (L, v); + return 4; + } else { + lua_pushnil (L); + return 1; + } +} + +static int +push_metadata_wpiterator (lua_State *L, WpIterator *it) +{ + lua_pushcfunction (L, metadata_iterator_next); + wplua_pushboxed (L, WP_TYPE_ITERATOR, it); + return 2; +} + /* WpObjectInterest */ static GVariant * @@ -314,9 +344,54 @@ object_manager_iterate (lua_State *L) return push_wpiterator (L, it); } +static int +object_manager_lookup (lua_State *L) +{ + WpObjectManager *om = wplua_checkobject (L, 1, WP_TYPE_OBJECT_MANAGER); + WpObject *o = NULL; + if (lua_isuserdata (L, 2)) { + WpObjectInterest *oi = wplua_checkboxed (L, 2, WP_TYPE_OBJECT_INTEREST); + o = wp_object_manager_lookup_full (om, oi); + } else { + o = wp_object_manager_lookup (om, WP_TYPE_OBJECT, NULL); + } + wplua_pushobject (L, o); + return 1; +} + static const luaL_Reg object_manager_methods[] = { { "activate", object_manager_activate }, { "iterate", object_manager_iterate }, + { "lookup", object_manager_lookup }, + { NULL, NULL } +}; + +/* WpMetadata */ + +static int +metadata_iterate (lua_State *L) +{ + WpMetadata *metadata = wplua_checkobject (L, 1, WP_TYPE_METADATA); + lua_Integer subject = luaL_checkinteger (L, 2); + g_autoptr (WpIterator) it = wp_metadata_iterate (metadata, subject); + return push_metadata_wpiterator (L, it); +} + +static int +metadata_find (lua_State *L) +{ + WpMetadata *metadata = wplua_checkobject (L, 1, WP_TYPE_METADATA); + lua_Integer subject = luaL_checkinteger (L, 2); + const char *key = luaL_checkstring (L, 3), *v = NULL, *t = NULL; + v = wp_metadata_find (metadata, subject, key, &t); + lua_pushstring (L, v); + lua_pushstring (L, t); + return 2; +} + +static const luaL_Reg metadata_methods[] = { + { "iterate", metadata_iterate }, + { "find", metadata_find }, { NULL, NULL } }; @@ -433,6 +508,8 @@ wp_lua_scripting_api_init (lua_State *L) object_interest_new, NULL); wplua_register_type_methods (L, WP_TYPE_OBJECT_MANAGER, object_manager_new, object_manager_methods); + wplua_register_type_methods (L, WP_TYPE_METADATA, + NULL, metadata_methods); wplua_register_type_methods (L, WP_TYPE_SESSION, NULL, session_methods); wplua_register_type_methods (L, WP_TYPE_ENDPOINT, diff --git a/src/config/desktop/policy-endpoint.lua b/src/config/desktop/policy-endpoint.lua index 6c71add83a3534596fbeae1d1a089b7a79aed00e..1ad85c1ee1e8821bcb682a3136ecef0b52f40fee 100644 --- a/src/config/desktop/policy-endpoint.lua +++ b/src/config/desktop/policy-endpoint.lua @@ -17,6 +17,11 @@ reverse_direction = { ["output"] = "input", } +default_endpoint_key = { + ["input"] = "default.session.endpoint.sink", + ["output"] = "default.session.endpoint.source", +} + function findTarget (session, ep) local target = nil @@ -39,6 +44,7 @@ function findTarget (session, ep) -- try to find the best target if not target then + local metadata = om_metadata:lookup() local direction = reverse_direction[ep['direction']] local media_class = target_class_assoc[ep['media-class']] local highest_prio = -1 @@ -47,13 +53,16 @@ function findTarget (session, ep) if candidate_ep['direction'] == direction and candidate_ep['media-class'] == media_class then - --[[ - if candidate_ep['bound-id'] == session.default_target[direction] then - target = candidate_ep - Log.debug(session, "choosing default endpoint " .. target['bound-id']); - break + -- honor default endpoint, if present + if metadata then + local key = default_endpoint_key[direction] + local value = metadata:find(session['bound-id'], key) + if candidate_ep['bound-id'] == tonumber(value) then + target = candidate_ep + Log.debug(session, "choosing default endpoint " .. target['bound-id']); + break + end end - ]] local prio = tonumber(candidate_ep.properties["endpoint.priority"]) or 0 if highest_prio < prio then @@ -108,6 +117,7 @@ function handleLink (link) end end +om_metadata = ObjectManager { Interest { type = "metadata" } } om = ObjectManager { Interest { type = "session" } } om:connect("object-added", function (om, session) @@ -124,4 +134,5 @@ om:connect("object-added", function (om, session) end) end) +om_metadata:activate() om:activate()