summaryrefslogtreecommitdiffstats
path: root/options
diff options
context:
space:
mode:
Diffstat (limited to 'options')
-rw-r--r--options/m_property.c61
-rw-r--r--options/m_property.h28
2 files changed, 88 insertions, 1 deletions
diff --git a/options/m_property.c b/options/m_property.c
index 9c8649c5ab..d863a06ab3 100644
--- a/options/m_property.c
+++ b/options/m_property.c
@@ -386,3 +386,64 @@ int m_property_strdup_ro(const struct m_option* prop, int action, void* arg,
}
return M_PROPERTY_NOT_IMPLEMENTED;
}
+
+// This allows you to make a list of values (like from a struct) available
+// as a number of sub-properties. The property list is set up with the current
+// property values on the stack before calling this function.
+// This does not support write access.
+int m_property_read_sub(const struct m_sub_property *props, int action, void *arg)
+{
+ switch (action) {
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)arg = (struct m_option){
+ .name = "",
+ .type = CONF_TYPE_STRING,
+ };
+ return M_PROPERTY_OK;
+ case M_PROPERTY_GET:
+ case M_PROPERTY_PRINT: {
+ // Output "something" - what it really should return is not yet decided.
+ // It should probably be something that is easy to consume by slave
+ // mode clients. (M_PROPERTY_PRINT on the other hand can return this
+ // as human readable version just fine).
+ char *res = NULL;
+ for (int n = 0; props && props[n].name; n++) {
+ const struct m_sub_property *prop = &props[n];
+ if (prop->unavailable)
+ continue;
+ struct m_option type = { .name = "", .type = prop->type, };
+ char *s = m_option_print(&type, &prop->value);
+ ta_xasprintf_append(&res, "%s=%s\n", prop->name, s);
+ talloc_free(s);
+ }
+ *(char **)arg = res;
+ return M_PROPERTY_OK;
+ }
+ case M_PROPERTY_KEY_ACTION: {
+ struct m_property_action_arg *ka = arg;
+ const struct m_sub_property *prop = NULL;
+ for (int n = 0; props && props[n].name; n++) {
+ if (strcmp(props[n].name, ka->key) == 0) {
+ prop = &props[n];
+ break;
+ }
+ }
+ if (!prop)
+ return M_PROPERTY_UNKNOWN;
+ if (prop->unavailable)
+ return M_PROPERTY_UNAVAILABLE;
+ struct m_option type = { .name = "", .type = prop->type, };
+ switch (ka->action) {
+ case M_PROPERTY_GET: {
+ memset(ka->arg, 0, type.type->size);
+ m_option_copy(&type, ka->arg, &prop->value);
+ return M_PROPERTY_OK;
+ }
+ case M_PROPERTY_GET_TYPE:
+ *(struct m_option *)ka->arg = type;
+ return M_PROPERTY_OK;
+ }
+ }
+ }
+ return M_PROPERTY_NOT_IMPLEMENTED;
+}
diff --git a/options/m_property.h b/options/m_property.h
index ae4b7716b6..cb9f8b5a25 100644
--- a/options/m_property.h
+++ b/options/m_property.h
@@ -22,7 +22,8 @@
#include <stdbool.h>
#include <stdint.h>
-struct m_option;
+#include "m_option.h"
+
struct mp_log;
extern const struct m_option_type m_option_type_dummy;
@@ -141,4 +142,29 @@ int m_property_double_ro(const struct m_option* prop, int action, void* arg,
int m_property_strdup_ro(const struct m_option* prop, int action, void* arg,
const char *var);
+struct m_sub_property {
+ // Name of the sub-property - this will be prefixed with the parent
+ // property's name.
+ const char *name;
+ // Type of the data stored in the value member. See m_option.
+ const struct m_option_type *type;
+ // Data returned by the sub-property. m_property_read_sub() will make a
+ // copy of this if needed. It will never write or free the data.
+ union m_option_value value;
+ // This can be set to true if the property should be hidden.
+ bool unavailable;
+};
+
+// Convenience macros which can be used as part of a sub_property entry.
+#define SUB_PROP_INT(i) \
+ .type = CONF_TYPE_INT, .value = {.int_ = (i)}
+#define SUB_PROP_STR(s) \
+ .type = CONF_TYPE_STRING, .value = {.string = (char *)(s)}
+#define SUB_PROP_FLOAT(f) \
+ .type = CONF_TYPE_FLOAT, .value = {.float_ = (f)}
+#define SUB_PROP_FLAG(f) \
+ .type = CONF_TYPE_FLAG, .value = {.flag = (f)}
+
+int m_property_read_sub(const struct m_sub_property *props, int action, void *arg);
+
#endif /* MPLAYER_M_PROPERTY_H */