summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options/m_config.c31
-rw-r--r--options/m_config.h6
-rw-r--r--player/client.c17
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: