diff options
-rw-r--r-- | options/m_config.c | 31 | ||||
-rw-r--r-- | options/m_config.h | 6 | ||||
-rw-r--r-- | player/client.c | 17 |
3 files changed, 50 insertions, 4 deletions
diff --git a/options/m_config.c b/options/m_config.c index 4b520c758a..d2b75389fe 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -28,6 +28,8 @@ #include <assert.h> #include <stdbool.h> +#include "libmpv/client.h" + #include "talloc.h" #include "m_config.h" @@ -606,6 +608,35 @@ int m_config_set_option(struct m_config *config, struct bstr name, return m_config_set_option_ext(config, name, param, 0); } +int m_config_set_option_node(struct m_config *config, bstr name, + struct mpv_node *data, int flags) +{ + char *value = NULL; + if (data->format == MPV_FORMAT_STRING) { + value = *(char **)data; + } else { + // This is pretty lame, but the simplest for now. It will fail very + // hard for string lists with items that contain ',' characters. + union m_option_value val = {0}; + const struct m_option *opt = m_config_get_option(config, name); + if (!opt) + return M_OPT_UNKNOWN; + if (m_option_set_node(opt, &val, data) < 0) + return M_OPT_INVALID; + value = m_option_print(opt, &val); + m_option_free(opt, &val); + } + int r; + if (value) { + r = m_config_set_option_ext(config, name, bstr0(value), flags); + } else { + r = M_OPT_OUT_OF_RANGE; + } + if (data->format != MPV_FORMAT_STRING) + talloc_free(value); + return r; +} + const struct m_option *m_config_get_option(const struct m_config *config, struct bstr name) { diff --git a/options/m_config.h b/options/m_config.h index 2624f45edf..82382aaa27 100644 --- a/options/m_config.h +++ b/options/m_config.h @@ -139,6 +139,12 @@ static inline int m_config_set_option0(struct m_config *config, return m_config_set_option(config, bstr0(name), bstr0(param)); } +// Same as m_config_set_option_ext(), but set as data using mpv_node. +struct mpv_node; +int m_config_set_option_node(struct m_config *config, bstr name, + struct mpv_node *data, int flags); + + int m_config_parse_suboptions(struct m_config *config, char *name, char *subopts); diff --git a/player/client.c b/player/client.c index d61c0a5056..11fe86bdfc 100644 --- a/player/client.c +++ b/player/client.c @@ -508,15 +508,24 @@ int mpv_set_option(mpv_handle *ctx, const char *name, mpv_format format, return err; } } else { - if (format != MPV_FORMAT_STRING) + const struct m_option *type = get_mp_type(format); + if (!type) return MPV_ERROR_OPTION_FORMAT; - const char *value = *(char **)data; - int err = m_config_set_option0(ctx->mpctx->mconfig, name, value); + struct mpv_node tmp; + if (format != MPV_FORMAT_NODE) { + tmp.format = format; + memcpy(&tmp.u, data, type->type->size); + format = MPV_FORMAT_NODE; + data = &tmp; + } + int err = m_config_set_option_node(ctx->mpctx->mconfig, bstr0(name), + data, 0); switch (err) { case M_OPT_MISSING_PARAM: case M_OPT_INVALID: - case M_OPT_OUT_OF_RANGE: return MPV_ERROR_OPTION_ERROR; + case M_OPT_OUT_OF_RANGE: + return MPV_ERROR_OPTION_FORMAT; case M_OPT_UNKNOWN: return MPV_ERROR_OPTION_NOT_FOUND; default: |