mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
conf: improve config files
Make arrays from config sections that should really be an array. Having the module name as the object key technically makes it impossible to load the same module twice because the key can only be once in the object. The same applies to the context.objects and context.exec sections. This also makes it somewhat easier to parse the config..
This commit is contained in:
parent
86cf4ad5a5
commit
90b0410280
7 changed files with 171 additions and 168 deletions
|
|
@ -19,9 +19,9 @@ context.spa-libs = {
|
|||
support.* = support/libspa-support
|
||||
}
|
||||
|
||||
context.modules = {
|
||||
#<module-name> = {
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
context.modules = [
|
||||
#{ name = <module-name>
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
# [ flags = [ [ ifexists ] [ nofail ] ]
|
||||
#}
|
||||
#
|
||||
|
|
@ -30,7 +30,7 @@ context.modules = {
|
|||
# If nofail is given, module initialization failures are ignored.
|
||||
#
|
||||
# Uses RTKit to boost the data thread priority.
|
||||
libpipewire-module-rtkit = {
|
||||
{ name = libpipewire-module-rtkit
|
||||
args = {
|
||||
#nice.level = -11
|
||||
#rt.prio = 88
|
||||
|
|
@ -41,28 +41,28 @@ context.modules = {
|
|||
}
|
||||
|
||||
# The native communication protocol.
|
||||
libpipewire-module-protocol-native = null
|
||||
{ name = libpipewire-module-protocol-native }
|
||||
|
||||
# Allows creating nodes that run in the context of the
|
||||
# client. Is used by all clients that want to provide
|
||||
# data to PipeWire.
|
||||
libpipewire-module-client-node = null
|
||||
{ name = libpipewire-module-client-node }
|
||||
|
||||
# Allows creating devices that run in the context of the
|
||||
# client. Is used by the session manager.
|
||||
libpipewire-module-client-device = null
|
||||
{ name = libpipewire-module-client-device }
|
||||
|
||||
# Makes a factory for wrapping nodes in an adapter with a
|
||||
# converter and resampler.
|
||||
libpipewire-module-adapter = null
|
||||
{ name = libpipewire-module-adapter }
|
||||
|
||||
# Allows applications to create metadata objects. It creates
|
||||
# a factory for Metadata objects.
|
||||
libpipewire-module-metadata = null
|
||||
{ name = libpipewire-module-metadata }
|
||||
|
||||
# Provides factories to make session manager objects.
|
||||
libpipewire-module-session-manager = null
|
||||
}
|
||||
{ name = libpipewire-module-session-manager }
|
||||
]
|
||||
|
||||
filter.properties = {
|
||||
#node.latency = 1024/48000
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ context.spa-libs = {
|
|||
support.* = support/libspa-support
|
||||
}
|
||||
|
||||
context.modules = {
|
||||
#<module-name> = {
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
context.modules = [
|
||||
#{ name = <module-name>
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
# [ flags = [ [ ifexists ] [ nofail ] ]
|
||||
#}
|
||||
#
|
||||
|
|
@ -30,28 +30,28 @@ context.modules = {
|
|||
#
|
||||
|
||||
# The native communication protocol.
|
||||
libpipewire-module-protocol-native = null
|
||||
{ name = libpipewire-module-protocol-native }
|
||||
|
||||
# Allows creating nodes that run in the context of the
|
||||
# client. Is used by all clients that want to provide
|
||||
# data to PipeWire.
|
||||
libpipewire-module-client-node = null
|
||||
{ name = libpipewire-module-client-node }
|
||||
|
||||
# Allows creating devices that run in the context of the
|
||||
# client. Is used by the session manager.
|
||||
libpipewire-module-client-device = null
|
||||
{ name = libpipewire-module-client-device }
|
||||
|
||||
# Makes a factory for wrapping nodes in an adapter with a
|
||||
# converter and resampler.
|
||||
libpipewire-module-adapter = null
|
||||
{ name = libpipewire-module-adapter }
|
||||
|
||||
# Allows applications to create metadata objects. It creates
|
||||
# a factory for Metadata objects.
|
||||
libpipewire-module-metadata = null
|
||||
{ name = libpipewire-module-metadata }
|
||||
|
||||
# Provides factories to make session manager objects.
|
||||
libpipewire-module-session-manager = null
|
||||
}
|
||||
{ name = libpipewire-module-session-manager }
|
||||
]
|
||||
|
||||
filter.properties = {
|
||||
#node.latency = 1024/48000
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ context.spa-libs = {
|
|||
support.* = support/libspa-support
|
||||
}
|
||||
|
||||
context.modules = {
|
||||
#<module-name> = {
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
context.modules = [
|
||||
#{ name = <module-name>
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
# [ flags = [ [ ifexists ] [ nofail ] ]
|
||||
#}
|
||||
#
|
||||
|
|
@ -30,7 +30,7 @@ context.modules = {
|
|||
#
|
||||
#
|
||||
# Uses RTKit to boost the data thread priority.
|
||||
libpipewire-module-rtkit = {
|
||||
{ name = libpipewire-module-rtkit
|
||||
args = {
|
||||
#nice.level = -11
|
||||
#rt.prio = 88
|
||||
|
|
@ -41,17 +41,17 @@ context.modules = {
|
|||
}
|
||||
|
||||
# The native communication protocol.
|
||||
libpipewire-module-protocol-native = null
|
||||
{ name = libpipewire-module-protocol-native }
|
||||
|
||||
# Allows creating nodes that run in the context of the
|
||||
# client. Is used by all clients that want to provide
|
||||
# data to PipeWire.
|
||||
libpipewire-module-client-node = null
|
||||
{ name = libpipewire-module-client-node }
|
||||
|
||||
# Allows applications to create metadata objects. It creates
|
||||
# a factory for Metadata objects.
|
||||
libpipewire-module-metadata = null
|
||||
}
|
||||
{ name = libpipewire-module-metadata }
|
||||
]
|
||||
|
||||
jack.properties = {
|
||||
#node.latency = 1024/48000
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ context.spa-libs = {
|
|||
api.libcamera.* = libcamera/libspa-libcamera
|
||||
}
|
||||
|
||||
context.modules = {
|
||||
#<module-name> = {
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
context.modules = [
|
||||
#{ name = <module-name>
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
# [ flags = [ [ ifexists ] [ nofail ] ]
|
||||
#}
|
||||
#
|
||||
|
|
@ -26,7 +26,7 @@ context.modules = {
|
|||
# If nofail is given, module initialization failures are ignored.
|
||||
#
|
||||
# Uses RTKit to boost the data thread priority.
|
||||
libpipewire-module-rtkit = {
|
||||
{ name = libpipewire-module-rtkit
|
||||
args = {
|
||||
#nice.level = -11
|
||||
#rt.prio = 88
|
||||
|
|
@ -37,28 +37,28 @@ context.modules = {
|
|||
}
|
||||
|
||||
# The native communication protocol.
|
||||
libpipewire-module-protocol-native = null
|
||||
{ name = libpipewire-module-protocol-native }
|
||||
|
||||
# Allows creating nodes that run in the context of the
|
||||
# client. Is used by all clients that want to provide
|
||||
# data to PipeWire.
|
||||
libpipewire-module-client-node = null
|
||||
{ name = libpipewire-module-client-node }
|
||||
|
||||
# Allows creating devices that run in the context of the
|
||||
# client. Is used by the session manager.
|
||||
libpipewire-module-client-device = null
|
||||
{ name = libpipewire-module-client-device }
|
||||
|
||||
# Makes a factory for wrapping nodes in an adapter with a
|
||||
# converter and resampler.
|
||||
libpipewire-module-adapter = null
|
||||
{ name = libpipewire-module-adapter }
|
||||
|
||||
# Allows applications to create metadata objects. It creates
|
||||
# a factory for Metadata objects.
|
||||
libpipewire-module-metadata = null
|
||||
{ name = libpipewire-module-metadata }
|
||||
|
||||
# Provides factories to make session manager objects.
|
||||
libpipewire-module-session-manager = null
|
||||
}
|
||||
{ name = libpipewire-module-session-manager }
|
||||
]
|
||||
|
||||
session.modules = {
|
||||
# These are the modules that are enabled when a file with
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ context.spa-libs = {
|
|||
support.* = support/libspa-support
|
||||
}
|
||||
|
||||
context.modules = {
|
||||
libpipewire-module-rtkit = {
|
||||
context.modules = [
|
||||
{ name = libpipewire-module-rtkit
|
||||
args = {
|
||||
#nice.level = -11
|
||||
#rt.prio = 88
|
||||
|
|
@ -22,12 +22,12 @@ context.modules = {
|
|||
}
|
||||
flags = [ ifexists nofail ]
|
||||
}
|
||||
libpipewire-module-protocol-native = null
|
||||
libpipewire-module-client-node = null
|
||||
libpipewire-module-adapter = null
|
||||
libpipewire-module-metadata = null
|
||||
{ name = libpipewire-module-protocol-native }
|
||||
{ name = libpipewire-module-client-node }
|
||||
{ name = libpipewire-module-adapter }
|
||||
{ name = libpipewire-module-metadata }
|
||||
|
||||
libpipewire-module-protocol-pulse = {
|
||||
{ name = libpipewire-module-protocol-pulse
|
||||
args = {
|
||||
# the addresses this server listens on
|
||||
server.address = [
|
||||
|
|
@ -42,7 +42,7 @@ context.modules = {
|
|||
#pulse.min.quantum = 256/48000 # 5ms
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
stream.properties = {
|
||||
#node.latency = 1024/48000
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ context.spa-libs = {
|
|||
#audiotestsrc = audiotestsrc/libspa-audiotestsrc
|
||||
}
|
||||
|
||||
context.modules = {
|
||||
#<module-name> = {
|
||||
context.modules = [
|
||||
#{ name = <module-name>
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
# [ flags = [ [ ifexists ] [ nofail ] ]
|
||||
#}
|
||||
|
|
@ -56,7 +56,7 @@ context.modules = {
|
|||
#
|
||||
|
||||
# Uses RTKit to boost the data thread priority.
|
||||
libpipewire-module-rtkit = {
|
||||
{ name = libpipewire-module-rtkit
|
||||
args = {
|
||||
#nice.level = -11
|
||||
#rt.prio = 88
|
||||
|
|
@ -67,44 +67,44 @@ context.modules = {
|
|||
}
|
||||
|
||||
# The native communication protocol.
|
||||
libpipewire-module-protocol-native = null
|
||||
{ name = libpipewire-module-protocol-native }
|
||||
|
||||
# The profile module. Allows application to access profiler
|
||||
# and performance data. It provides an interface that is used
|
||||
# by pw-top and pw-profiler.
|
||||
libpipewire-module-profiler = null
|
||||
{ name = libpipewire-module-profiler }
|
||||
|
||||
# Allows applications to create metadata objects. It creates
|
||||
# a factory for Metadata objects.
|
||||
libpipewire-module-metadata = null
|
||||
{ name = libpipewire-module-metadata }
|
||||
|
||||
# Creates a factory for making devices that run in the
|
||||
# context of the PipeWire server.
|
||||
libpipewire-module-spa-device-factory = null
|
||||
{ name = libpipewire-module-spa-device-factory }
|
||||
|
||||
# Creates a factory for making nodes that run in the
|
||||
# context of the PipeWire server.
|
||||
libpipewire-module-spa-node-factory = null
|
||||
{ name = libpipewire-module-spa-node-factory }
|
||||
|
||||
# Allows creating nodes that run in the context of the
|
||||
# client. Is used by all clients that want to provide
|
||||
# data to PipeWire.
|
||||
libpipewire-module-client-node = null
|
||||
{ name = libpipewire-module-client-node }
|
||||
|
||||
# Allows creating devices that run in the context of the
|
||||
# client. Is used by the session manager.
|
||||
libpipewire-module-client-device = null
|
||||
{ name = libpipewire-module-client-device }
|
||||
|
||||
# The portal module monitors the PID of the portal process
|
||||
# and tags connections with the same PID as portal
|
||||
# connections.
|
||||
libpipewire-module-portal = {
|
||||
{ name = libpipewire-module-portal
|
||||
flags = [ ifexists nofail ]
|
||||
}
|
||||
|
||||
# The access module can perform access checks and block
|
||||
# new clients.
|
||||
libpipewire-module-access = {
|
||||
{ name = libpipewire-module-access
|
||||
args = {
|
||||
# access.allowed to list an array of paths of allowed
|
||||
# apps.
|
||||
|
|
@ -126,17 +126,17 @@ context.modules = {
|
|||
|
||||
# Makes a factory for wrapping nodes in an adapter with a
|
||||
# converter and resampler.
|
||||
libpipewire-module-adapter = null
|
||||
{ name = libpipewire-module-adapter }
|
||||
|
||||
# Makes a factory for creating links between ports.
|
||||
libpipewire-module-link-factory = null
|
||||
{ name = libpipewire-module-link-factory }
|
||||
|
||||
# Provides factories to make session manager objects.
|
||||
libpipewire-module-session-manager = null
|
||||
}
|
||||
{ name = libpipewire-module-session-manager }
|
||||
]
|
||||
|
||||
context.objects = {
|
||||
#<factory-name> = {
|
||||
context.objects = [
|
||||
#{ factory = <factory-name>
|
||||
# [ args = { <key> = <value> ... } ]
|
||||
# [ flags = [ [ nofail ] ]
|
||||
#}
|
||||
|
|
@ -144,16 +144,16 @@ context.objects = {
|
|||
# Creates an object from a PipeWire factory with the given parameters.
|
||||
# If nofail is given, errors are ignored (and no object is created).
|
||||
#
|
||||
#spa-node-factory = { args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
|
||||
#spa-device-factory = { args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
|
||||
#spa-device-factory = { args = { factory.name = api.alsa.enum.udev } }
|
||||
#spa-device-factory = { args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
|
||||
#adapter = { args = { factory.name = audiotestsrc node.name = my-test } }
|
||||
#spa-node-factory = { args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
|
||||
#{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
|
||||
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
|
||||
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
|
||||
#{ factory = spa-device-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
|
||||
#{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test } }
|
||||
#{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
|
||||
|
||||
# A default dummy driver. This handles nodes marked with the "node.always-driver"
|
||||
# property when no other driver is currently active. JACK clients need this.
|
||||
spa-node-factory = {
|
||||
{ factory = spa-node-factory
|
||||
args = {
|
||||
factory.name = support.node.driver
|
||||
node.name = Dummy-Driver
|
||||
|
|
@ -162,7 +162,7 @@ context.objects = {
|
|||
}
|
||||
# This creates a new Source node. It will have input ports
|
||||
# that you can link, to provide audio for this source.
|
||||
#adapter = {
|
||||
#{ factory = adapter
|
||||
# args = {
|
||||
# factory.name = support.null-audio-sink
|
||||
# node.name = "my-mic"
|
||||
|
|
@ -175,7 +175,7 @@ context.objects = {
|
|||
# This creates a single PCM source device for the given
|
||||
# alsa device path hw:0. You can change source to sink
|
||||
# to make a sink in the same way.
|
||||
#adapter = {
|
||||
#{ factory = adapter
|
||||
# args = {
|
||||
# factory.name = api.alsa.pcm.source
|
||||
# node.name = "alsa-source"
|
||||
|
|
@ -192,10 +192,10 @@ context.objects = {
|
|||
# #audio.position = "FL,FR"
|
||||
# }
|
||||
#}
|
||||
}
|
||||
]
|
||||
|
||||
context.exec = {
|
||||
#<program-name> = { [ args = "<arguments>" ] }
|
||||
context.exec = [
|
||||
#{ path = <program-name> [ args = "<arguments>" ] }
|
||||
#
|
||||
# Execute the given program with arguments.
|
||||
#
|
||||
|
|
@ -203,12 +203,12 @@ context.exec = {
|
|||
# but it is better to start it as a systemd service.
|
||||
# Run the session manager with -h for options.
|
||||
#
|
||||
@comment@"@media_session_path@" = { args = "" }
|
||||
@comment@{ path = "@media_session_path@" args = "" }
|
||||
#
|
||||
# You can optionally start the pulseaudio-server here as well
|
||||
# but it is better to start it as a systemd service.
|
||||
# It can be interesting to start another daemon here that listens
|
||||
# on another address with the -a option (eg. -a tcp:4713).
|
||||
#
|
||||
@comment@"@pipewire_path@" = { args = "-c pipewire-pulse.conf" }
|
||||
}
|
||||
@comment@{ path = "@pipewire_path@" args = "-c pipewire-pulse.conf" }
|
||||
]
|
||||
|
|
|
|||
|
|
@ -273,6 +273,10 @@ int pw_conf_load_state(const char *prefix, const char *name, struct pw_propertie
|
|||
return conf_load(prefix, name, conf);
|
||||
}
|
||||
|
||||
/* context.spa-libs = {
|
||||
* <factory-name regex> = <library-name>
|
||||
* }
|
||||
*/
|
||||
static int parse_spa_libs(struct pw_context *context, const char *str)
|
||||
{
|
||||
struct spa_json it[2];
|
||||
|
|
@ -313,6 +317,14 @@ static int load_module(struct pw_context *context, const char *key, const char *
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* context.modules = [
|
||||
* { name = <module-name>
|
||||
* [ args = { <key> = <value> ... } ]
|
||||
* [ flags = [ [ ifexists ] [ nofail ] ]
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
static int parse_modules(struct pw_context *context, const char *str)
|
||||
{
|
||||
struct spa_json it[3];
|
||||
|
|
@ -320,49 +332,41 @@ static int parse_modules(struct pw_context *context, const char *str)
|
|||
int res = 0;
|
||||
|
||||
spa_json_init(&it[0], str, strlen(str));
|
||||
if (spa_json_enter_object(&it[0], &it[1]) < 0)
|
||||
if (spa_json_enter_array(&it[0], &it[1]) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
while (spa_json_get_string(&it[1], key, sizeof(key)-1) > 0) {
|
||||
const char *val, *aval;
|
||||
char *args = NULL, *flags = NULL;
|
||||
int len, alen;
|
||||
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
|
||||
char *name = NULL, *args = NULL, *flags = NULL;
|
||||
|
||||
if ((len = spa_json_next(&it[1], &val)) <= 0)
|
||||
break;
|
||||
while (spa_json_get_string(&it[2], key, sizeof(key)-1) > 0) {
|
||||
const char *val;
|
||||
int len;
|
||||
|
||||
if (key[0] == '#')
|
||||
continue;
|
||||
if ((len = spa_json_next(&it[2], &val)) <= 0)
|
||||
break;
|
||||
|
||||
if (spa_json_is_object(val, len)) {
|
||||
char arg[512];
|
||||
if (strcmp(key, "name") == 0) {
|
||||
name = malloc(len + 1);
|
||||
spa_json_parse_string(val, len, name);
|
||||
}
|
||||
else if (strcmp(key, "args") == 0) {
|
||||
if (spa_json_is_container(val, len))
|
||||
len = spa_json_container_len(&it[2], val, len);
|
||||
|
||||
spa_json_enter(&it[1], &it[2]);
|
||||
args = malloc(len + 1);
|
||||
spa_json_parse_string(val, len, args);
|
||||
} else if (strcmp(key, "flags") == 0) {
|
||||
if (spa_json_is_container(val, len))
|
||||
len = spa_json_container_len(&it[2], val, len);
|
||||
|
||||
while (spa_json_get_string(&it[2], arg, sizeof(arg)-1) > 0) {
|
||||
if ((alen = spa_json_next(&it[2], &aval)) <= 0)
|
||||
break;
|
||||
|
||||
if (strcmp(arg, "args") == 0) {
|
||||
if (spa_json_is_container(aval, alen))
|
||||
alen = spa_json_container_len(&it[2], aval, alen);
|
||||
|
||||
args = malloc(alen + 1);
|
||||
spa_json_parse_string(aval, alen, args);
|
||||
} else if (strcmp(arg, "flags") == 0) {
|
||||
if (spa_json_is_container(aval, alen))
|
||||
alen = spa_json_container_len(&it[2], aval, alen);
|
||||
|
||||
flags = malloc(alen + 1);
|
||||
spa_json_parse_string(aval, alen, flags);
|
||||
}
|
||||
flags = malloc(len + 1);
|
||||
spa_json_parse_string(val, len, flags);
|
||||
}
|
||||
}
|
||||
else if (!spa_json_is_null(val, len))
|
||||
break;
|
||||
|
||||
res = load_module(context, key, args, flags);
|
||||
if (name != NULL)
|
||||
res = load_module(context, name, args, flags);
|
||||
|
||||
free(name);
|
||||
free(args);
|
||||
free(flags);
|
||||
|
||||
|
|
@ -399,6 +403,14 @@ static int create_object(struct pw_context *context, const char *key, const char
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* context.objects = [
|
||||
* { factory = <factory-name>
|
||||
* [ args = { <key> = <value> ... } ]
|
||||
* [ flags = [ [ nofail ] ] ]
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
static int parse_objects(struct pw_context *context, const char *str)
|
||||
{
|
||||
struct spa_json it[3];
|
||||
|
|
@ -406,45 +418,36 @@ static int parse_objects(struct pw_context *context, const char *str)
|
|||
int res = 0;
|
||||
|
||||
spa_json_init(&it[0], str, strlen(str));
|
||||
if (spa_json_enter_object(&it[0], &it[1]) < 0)
|
||||
if (spa_json_enter_array(&it[0], &it[1]) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
while (spa_json_get_string(&it[1], key, sizeof(key)-1) > 0) {
|
||||
const char *val, *aval;
|
||||
char *args = NULL, *flags = NULL;
|
||||
int len, alen;
|
||||
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
|
||||
char *factory = NULL, *args = NULL, *flags = NULL;
|
||||
|
||||
if ((len = spa_json_next(&it[1], &val)) <= 0)
|
||||
break;
|
||||
while (spa_json_get_string(&it[2], key, sizeof(key)-1) > 0) {
|
||||
const char *val;
|
||||
int len;
|
||||
|
||||
if (key[0] == '#')
|
||||
continue;
|
||||
if ((len = spa_json_next(&it[2], &val)) <= 0)
|
||||
break;
|
||||
|
||||
if (spa_json_is_object(val, len)) {
|
||||
char arg[512];
|
||||
if (strcmp(key, "factory") == 0) {
|
||||
factory = malloc(len + 1);
|
||||
spa_json_parse_string(val, len, factory);
|
||||
} else if (strcmp(key, "args") == 0) {
|
||||
if (spa_json_is_container(val, len))
|
||||
len = spa_json_container_len(&it[2], val, len);
|
||||
|
||||
spa_json_enter(&it[1], &it[2]);
|
||||
|
||||
while (spa_json_get_string(&it[2], arg, sizeof(arg)-1) > 0) {
|
||||
if ((alen = spa_json_next(&it[2], &aval)) <= 0)
|
||||
break;
|
||||
|
||||
if (strcmp(arg, "args") == 0) {
|
||||
if (spa_json_is_container(aval, alen))
|
||||
alen = spa_json_container_len(&it[2], aval, alen);
|
||||
|
||||
args = malloc(alen + 1);
|
||||
spa_json_parse_string(aval, alen, args);
|
||||
} else if (strcmp(arg, "flags") == 0) {
|
||||
flags = strndup(aval, alen);
|
||||
}
|
||||
args = malloc(len + 1);
|
||||
spa_json_parse_string(val, len, args);
|
||||
} else if (strcmp(key, "flags") == 0) {
|
||||
flags = strndup(val, len);
|
||||
}
|
||||
}
|
||||
else if (!spa_json_is_null(val, len))
|
||||
break;
|
||||
|
||||
res = create_object(context, key, args, flags);
|
||||
if (factory != NULL)
|
||||
res = create_object(context, factory, args, flags);
|
||||
|
||||
free(factory);
|
||||
free(args);
|
||||
free(flags);
|
||||
|
||||
|
|
@ -485,6 +488,13 @@ static int do_exec(struct pw_context *context, const char *key, const char *args
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* context.exec = [
|
||||
* { path = <program-name>
|
||||
* [ args = "<arguments>" ]
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
static int parse_exec(struct pw_context *context, const char *str)
|
||||
{
|
||||
struct spa_json it[3];
|
||||
|
|
@ -492,38 +502,31 @@ static int parse_exec(struct pw_context *context, const char *str)
|
|||
int res = 0;
|
||||
|
||||
spa_json_init(&it[0], str, strlen(str));
|
||||
if (spa_json_enter_object(&it[0], &it[1]) < 0)
|
||||
if (spa_json_enter_array(&it[0], &it[1]) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
while (spa_json_get_string(&it[1], key, sizeof(key)-1) > 0) {
|
||||
const char *val;
|
||||
char *args = NULL;
|
||||
int len;
|
||||
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
|
||||
char *path = NULL, *args = NULL;
|
||||
|
||||
if ((len = spa_json_next(&it[1], &val)) <= 0)
|
||||
break;
|
||||
while (spa_json_get_string(&it[2], key, sizeof(key)-1) > 0) {
|
||||
const char *val;
|
||||
int len;
|
||||
|
||||
if (key[0] == '#')
|
||||
continue;
|
||||
if ((len = spa_json_next(&it[2], &val)) <= 0)
|
||||
break;
|
||||
|
||||
if (spa_json_is_object(val, len)) {
|
||||
char arg[512], aval[1024];
|
||||
|
||||
spa_json_enter(&it[1], &it[2]);
|
||||
|
||||
while (spa_json_get_string(&it[2], arg, sizeof(arg)-1) > 0) {
|
||||
if (spa_json_get_string(&it[2], aval, sizeof(aval)-1) <= 0)
|
||||
break;
|
||||
|
||||
if (strcmp(arg, "args") == 0)
|
||||
args = strdup(aval);
|
||||
if (strcmp(key, "path") == 0) {
|
||||
path = malloc(len + 1);
|
||||
spa_json_parse_string(val, len, path);
|
||||
} else if (strcmp(key, "args") == 0) {
|
||||
args = malloc(len + 1);
|
||||
spa_json_parse_string(val, len, args);
|
||||
}
|
||||
}
|
||||
else if (!spa_json_is_null(val, len))
|
||||
break;
|
||||
|
||||
res = do_exec(context, key, args);
|
||||
if (path)
|
||||
res = do_exec(context, path, args);
|
||||
|
||||
free(path);
|
||||
free(args);
|
||||
|
||||
if (res < 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue