summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/command.c215
-rw-r--r--core/input/input.c42
-rw-r--r--core/input/input.h10
-rw-r--r--core/m_config.c362
-rw-r--r--core/m_config.h92
-rw-r--r--core/m_option.c274
-rw-r--r--core/m_option.h16
-rw-r--r--core/m_property.c1
-rw-r--r--core/m_struct.c91
-rw-r--r--core/m_struct.h112
-rw-r--r--core/mp_core.h15
-rw-r--r--core/mp_msg.c251
-rw-r--r--core/mp_msg.h35
-rw-r--r--core/mplayer.c343
-rw-r--r--core/mpv_global.h12
-rw-r--r--core/options.c37
-rw-r--r--core/options.h5
-rw-r--r--core/parser-cfg.c9
-rw-r--r--core/parser-cfg.h3
-rw-r--r--core/parser-mpcmd.c12
-rw-r--r--core/screenshot.c8
-rw-r--r--core/timeline/tl_cue.c6
-rw-r--r--core/timeline/tl_edl.c4
-rw-r--r--core/timeline/tl_matroska.c12
24 files changed, 937 insertions, 1030 deletions
diff --git a/core/command.c b/core/command.c
index 00b6ed92f5..b7718e41b7 100644
--- a/core/command.c
+++ b/core/command.c
@@ -64,13 +64,14 @@
#ifdef CONFIG_DVDREAD
#include "stream/stream_dvd.h"
#endif
-#include "core/m_struct.h"
#include "screenshot.h"
#include "core/mp_core.h"
static void change_video_filters(MPContext *mpctx, const char *cmd,
const char *arg);
+static int set_filters(struct MPContext *mpctx, enum stream_type mediatype,
+ struct m_obj_settings *new_chain);
static char *format_bitrate(int rate)
{
@@ -122,11 +123,11 @@ static int mp_property_generic_option(struct m_option *prop, int action,
static int mp_property_playback_speed(m_option_t *prop, int action,
void *arg, MPContext *mpctx)
{
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
double orig_speed = opts->playback_speed;
switch (action) {
case M_PROPERTY_SET: {
- opts->playback_speed = *(float *) arg;
+ opts->playback_speed = *(double *) arg;
// Adjust time until next frame flip for nosound mode
mpctx->time_frame *= orig_speed / opts->playback_speed;
if (mpctx->sh_audio)
@@ -437,7 +438,7 @@ static int mp_property_list_chapters(m_option_t *prop, int action, void *arg,
static int mp_property_edition(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
@@ -752,13 +753,13 @@ static int mp_property_audio_delay(m_option_t *prop, int action,
{
if (!(mpctx->sh_audio && mpctx->sh_video))
return M_PROPERTY_UNAVAILABLE;
- float delay = mpctx->opts.audio_delay;
+ float delay = mpctx->opts->audio_delay;
switch (action) {
case M_PROPERTY_PRINT:
*(char **)arg = format_delay(delay);
return M_PROPERTY_OK;
case M_PROPERTY_SET:
- mpctx->audio_delay = mpctx->opts.audio_delay = *(float *)arg;
+ mpctx->audio_delay = mpctx->opts->audio_delay = *(float *)arg;
mpctx->delay -= mpctx->audio_delay - delay;
return M_PROPERTY_OK;
}
@@ -1139,7 +1140,7 @@ static int mp_property_colormatrix(m_option_t *prop, int action, void *arg,
if (action != M_PROPERTY_PRINT)
return video_refresh_property_helper(prop, action, arg, mpctx);
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
struct mp_csp_details vo_csp = {0};
if (mpctx->sh_video && mpctx->sh_video->vfilter)
@@ -1173,7 +1174,7 @@ static int mp_property_colormatrix_input_range(m_option_t *prop, int action,
if (action != M_PROPERTY_PRINT)
return video_refresh_property_helper(prop, action, arg, mpctx);
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
struct mp_csp_details vo_csp = {0};
if (mpctx->sh_video && mpctx->sh_video->vfilter)
@@ -1213,7 +1214,7 @@ static int mp_property_colormatrix_output_range(m_option_t *prop, int action,
return r;
}
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
int req = opts->requested_output_range;
struct mp_csp_details actual = {0};
@@ -1271,7 +1272,7 @@ static int mp_property_ontop(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
return mp_property_vo_flag(prop, action, arg, VOCTRL_ONTOP,
- &mpctx->opts.vo.ontop, mpctx);
+ &mpctx->opts->vo.ontop, mpctx);
}
/// Show window borders (RW)
@@ -1279,7 +1280,7 @@ static int mp_property_border(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
return mp_property_vo_flag(prop, action, arg, VOCTRL_BORDER,
- &mpctx->opts.vo.border, mpctx);
+ &mpctx->opts->vo.border, mpctx);
}
static int mp_property_framedrop(m_option_t *prop, int action,
@@ -1295,7 +1296,7 @@ static int mp_property_framedrop(m_option_t *prop, int action,
static int mp_property_gamma(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- int *gamma = (int *)((char *)&mpctx->opts + prop->offset);
+ int *gamma = (int *)((char *)mpctx->opts + prop->offset);
int r, val;
if (!mpctx->sh_video)
@@ -1425,7 +1426,7 @@ static int mp_property_aspect(m_option_t *prop, int action, void *arg,
float f = *(float *)arg;
if (f < 0.1)
f = (float)mpctx->sh_video->disp_w / mpctx->sh_video->disp_h;
- mpctx->opts.movie_aspect = f;
+ mpctx->opts->movie_aspect = f;
video_reinit_vo(mpctx->sh_video);
return M_PROPERTY_OK;
}
@@ -1460,7 +1461,7 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg,
static int mp_property_sub_delay(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
if (!mpctx->sh_video)
return M_PROPERTY_UNAVAILABLE;
switch (action) {
@@ -1474,7 +1475,7 @@ static int mp_property_sub_delay(m_option_t *prop, int action, void *arg,
static int mp_property_sub_pos(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
if (!mpctx->sh_video)
return M_PROPERTY_UNAVAILABLE;
if (action == M_PROPERTY_PRINT) {
@@ -1580,6 +1581,52 @@ static int mp_property_playlist(m_option_t *prop, int action, void *arg,
return M_PROPERTY_NOT_IMPLEMENTED;
}
+static char *print_obj_osd_list(struct m_obj_settings *list)
+{
+ char *res = NULL;
+ for (int n = 0; list && list[n].name; n++) {
+ res = talloc_asprintf_append(res, "%s [", list[n].name);
+ for (int i = 0; list[n].attribs && list[n].attribs[i]; i += 2) {
+ res = talloc_asprintf_append(res, "%s%s=%s", i > 0 ? " " : "",
+ list[n].attribs[i],
+ list[n].attribs[i + 1]);
+ }
+ res = talloc_asprintf_append(res, "]\n");
+ }
+ if (!res)
+ res = talloc_strdup(NULL, "(empty)");
+ return res;
+}
+
+static int property_filter(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx, enum stream_type mt)
+{
+ switch (action) {
+ case M_PROPERTY_PRINT: {
+ struct m_config_option *opt = m_config_get_co(mpctx->mconfig,
+ bstr0(prop->name));
+ *(char **)arg = print_obj_osd_list(*(struct m_obj_settings **)opt->data);
+ return M_PROPERTY_OK;
+ }
+ case M_PROPERTY_SET:
+ return set_filters(mpctx, mt, *(struct m_obj_settings **)arg) >= 0
+ ? M_PROPERTY_OK : M_PROPERTY_ERROR;
+ }
+ return mp_property_generic_option(prop, action, arg, mpctx);
+}
+
+static int mp_property_vf(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ return property_filter(prop, action, arg, mpctx, STREAM_VIDEO);
+}
+
+static int mp_property_af(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ return property_filter(prop, action, arg, mpctx, STREAM_AUDIO);
+}
+
static int mp_property_alias(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
@@ -1605,6 +1652,8 @@ static int mp_property_options(m_option_t *prop, int action, void *arg,
bstr0(ka->key));
if (!opt)
return M_PROPERTY_UNKNOWN;
+ if (!opt->data)
+ return M_PROPERTY_UNAVAILABLE;
switch (ka->action) {
case M_PROPERTY_GET:
@@ -1773,6 +1822,9 @@ static const m_option_t mp_properties[] = {
M_OPTION_PROPERTY_CUSTOM("ass-style-override", property_osd_helper),
#endif
+ M_OPTION_PROPERTY_CUSTOM("vf*", mp_property_vf),
+ M_OPTION_PROPERTY_CUSTOM("af*", mp_property_af),
+
#ifdef CONFIG_TV
{ "tv-brightness", mp_property_tv_color, CONF_TYPE_INT,
M_OPT_RANGE, -100, 100, .offset = TV_COLOR_BRIGHTNESS },
@@ -1828,6 +1880,8 @@ static struct property_osd_display {
int osd_id;
// Needs special ways to display the new value (seeks are delayed)
int seek_msg, seek_bar;
+ // Separator between option name and value (default: ": ")
+ const char *sep;
} property_osd_display[] = {
// general
{ "loop", _("Loop") },
@@ -1868,6 +1922,8 @@ static struct property_osd_display {
{ "sub-scale", _("Sub Scale")},
{ "ass-vsfilter-aspect-compat", _("Subtitle VSFilter aspect compat")},
{ "ass-style-override", _("ASS subtitle style override")},
+ { "vf*", _("Video filters"), .sep = ":\n"},
+ { "af*", _("Audio filters"), .sep = ":\n"},
#ifdef CONFIG_TV
{ "tv-brightness", _("Brightness"), .osd_progbar = OSD_BRIGHTNESS },
{ "tv-hue", _("Hue"), .osd_progbar = OSD_HUE},
@@ -1880,7 +1936,7 @@ static struct property_osd_display {
static void show_property_osd(MPContext *mpctx, const char *pname,
enum mp_on_osd osd_mode)
{
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
struct m_option prop = {0};
struct property_osd_display *p;
@@ -1941,12 +1997,16 @@ static void show_property_osd(MPContext *mpctx, const char *pname,
"%s: (unavailable)", osd_name);
} else if (r >= 0 && val) {
int osd_id = 0;
+ const char *sep = NULL;
if (p) {
int index = p - property_osd_display;
osd_id = p->osd_id ? p->osd_id : OSD_MSG_PROPERTY + index;
+ sep = p->sep;
}
+ if (!sep)
+ sep = ": ";
set_osd_tmsg(mpctx, osd_id, 1, opts->osd_duration,
- "%s: %s", osd_name, val);
+ "%s%s%s", osd_name, sep, val);
talloc_free(val);
}
}
@@ -1978,61 +2038,89 @@ static bool reinit_filters(MPContext *mpctx, enum stream_type mediatype)
return false;
}
-static void change_filters(MPContext *mpctx, enum stream_type mediatype,
- const char *cmd, const char *arg)
+static const char *filter_opt[STREAM_TYPE_COUNT] = {
+ [STREAM_VIDEO] = "vf",
+ [STREAM_AUDIO] = "af",
+};
+
+static int set_filters(struct MPContext *mpctx, enum stream_type mediatype,
+ struct m_obj_settings *new_chain)
{
- struct MPOpts *opts = &mpctx->opts;
- struct m_config *conf = mpctx->mconfig;
- struct m_obj_settings *old_settings = NULL;
- bool success = false;
- bool need_refresh = false;
- const char *option;
- struct m_obj_settings **list;
+ bstr option = bstr0(filter_opt[mediatype]);
+ struct m_config_option *co = m_config_get_co(mpctx->mconfig, option);
+ if (!co)
+ return -1;
- switch (mediatype) {
- case STREAM_VIDEO:
- option = "vf";
- list = &opts->vf_settings;
- break;
- case STREAM_AUDIO:
- option = "af";
- list = &opts->af_settings;
- break;
+ struct m_obj_settings **list = co->data;
+ struct m_obj_settings *old_settings = *list;
+ *list = NULL;
+ m_option_copy(co->opt, list, &new_chain);
+
+ bool success = reinit_filters(mpctx, mediatype);
+
+ if (success) {
+ m_option_free(co->opt, &old_settings);
+ } else {
+ m_option_free(co->opt, list);
+ *list = old_settings;
+ reinit_filters(mpctx, mediatype);
}
+ if (mediatype == STREAM_VIDEO)
+ mp_force_video_refresh(mpctx);
+
+ return success ? 0 : -1;
+}
+
+static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype,
+ const char *cmd, const char *arg)
+{
+ bstr option = bstr0(filter_opt[mediatype]);
+ struct m_config_option *co = m_config_get_co(mpctx->mconfig, option);
+ if (!co)
+ return -1;
+
// The option parser is used to modify the filter list itself.
char optname[20];
- snprintf(optname, sizeof(optname), "%s-%s", option, cmd);
- const struct m_option *type = m_config_get_option(conf, bstr0(optname));
+ snprintf(optname, sizeof(optname), "%.*s-%s", BSTR_P(option), cmd);
- // Backup old settings, in case it fails
- m_option_copy(type, &old_settings, list);
+ struct m_obj_settings *new_chain = NULL;
+ m_option_copy(co->opt, &new_chain, co->data);
- if (m_config_set_option0(conf, optname, arg) >= 0) {
- need_refresh = true;
- success = reinit_filters(mpctx, mediatype);
- }
+ int r = m_option_parse(co->opt, bstr0(optname), bstr0(arg), &new_chain);
+ if (r >= 0)
+ r = set_filters(mpctx, mediatype, new_chain);
- if (!success) {
- m_option_copy(type, list, &old_settings);
- if (need_refresh)
- reinit_filters(mpctx, mediatype);
- }
- m_option_free(type, &old_settings);
+ m_option_free(co->opt, &new_chain);
- if (need_refresh && mediatype == STREAM_VIDEO)
- mp_force_video_refresh(mpctx);
+ return r >= 0 ? 0 : -1;
+}
+
+static int edit_filters_osd(struct MPContext *mpctx, enum stream_type mediatype,
+ const char *cmd, const char *arg, bool on_osd)
+{
+ int r = edit_filters(mpctx, mediatype, cmd, arg);
+ if (on_osd) {
+ if (r >= 0) {
+ const char *prop = filter_opt[mediatype];
+ show_property_osd(mpctx, prop, MP_ON_OSD_MSG);
+ } else {
+ set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, mpctx->opts->osd_duration,
+ "Changing filters failed!");
+ }
+ }
+ return r;
}
static void change_video_filters(MPContext *mpctx, const char *cmd,
const char *arg)
{
- change_filters(mpctx, STREAM_VIDEO, cmd, arg);
+ edit_filters(mpctx, STREAM_VIDEO, cmd, arg);
}
void run_command(MPContext *mpctx, mp_cmd_t *cmd)
{
- struct MPOpts *opts = &mpctx->opts;
+ struct MPOpts *opts = mpctx->opts;
sh_video_t *const sh_video = mpctx->sh_video;
int osd_duration = opts->osd_duration;
bool auto_osd = cmd->on_osd == MP_ON_OSD_AUTO;
@@ -2098,8 +2186,8 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
.inc = 1,
.wrap = cmd->id == MP_CMD_CYCLE,
};
- if (cmd->args[1].v.f)
- s.inc = cmd->args[1].v.f;
+ if (cmd->args[1].v.d)
+ s.inc = cmd->args[1].v.d;
int r = mp_property_do(cmd->args[0].v.s, M_PROPERTY_SWITCH, &s, mpctx);
if (r == M_PROPERTY_OK || r == M_PROPERTY_UNAVAILABLE) {
show_property_osd(mpctx, cmd->args[0].v.s, cmd->on_osd);
@@ -2133,8 +2221,8 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
}
case MP_CMD_SPEED_MULT: {
- float v = cmd->args[0].v.f;
- v *= mpctx->opts.playback_speed;
+ double v = cmd->args[0].v.d;
+ v *= mpctx->opts->playback_speed;
mp_property_do("speed", M_PROPERTY_SET, &v, mpctx);
show_property_osd(mpctx, "speed", cmd->on_osd);
break;
@@ -2150,7 +2238,8 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
case MP_CMD_QUIT:
mpctx->stop_play = PT_QUIT;
- mpctx->quit_player_rc = cmd->args[0].v.i;
+ mpctx->quit_custom_rc = cmd->args[0].v.i;
+ mpctx->has_quit_custom_rc = true;
break;
case MP_CMD_QUIT_WATCH_LATER:
@@ -2312,7 +2401,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
else
radio_step_channel(mpctx->stream, RADIO_CHANNEL_LOWER);
if (radio_get_channel_name(mpctx->stream)) {
- set_osd_tmsg(OSD_MSG_RADIO_CHANNEL, osdl, osd_duration,
+ set_osd_tmsg(mpctx, OSD_MSG_RADIO_CHANNEL, osdl, osd_duration,
"Channel: %s",
radio_get_channel_name(mpctx->stream));
}
@@ -2323,7 +2412,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
if (mpctx->stream && mpctx->stream->type == STREAMTYPE_RADIO) {
radio_set_channel(mpctx->stream, cmd->args[0].v.s);
if (radio_get_channel_name(mpctx->stream)) {
- set_osd_tmsg(OSD_MSG_RADIO_CHANNEL, osdl, osd_duration,
+ set_osd_tmsg(mpctx, OSD_MSG_RADIO_CHANNEL, osdl, osd_duration,
"Channel: %s",
radio_get_channel_name(mpctx->stream));
}
@@ -2550,11 +2639,13 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
break;
case MP_CMD_AF:
- change_filters(mpctx, STREAM_AUDIO, cmd->args[0].v.s, cmd->args[1].v.s);
+ edit_filters_osd(mpctx, STREAM_AUDIO, cmd->args[0].v.s,
+ cmd->args[1].v.s, msg_osd);
break;
case MP_CMD_VF:
- change_video_filters(mpctx, cmd->args[0].v.s, cmd->args[1].v.s);
+ edit_filters_osd(mpctx, STREAM_VIDEO, cmd->args[0].v.s,
+ cmd->args[1].v.s, msg_osd);
break;
case MP_CMD_COMMAND_LIST: {
diff --git a/core/input/input.c b/core/input/input.c
index 7a016a0e4f..ae1358a76d 100644
--- a/core/input/input.c
+++ b/core/input/input.c
@@ -92,13 +92,14 @@ struct key_name {
#define ARG_INT { .type = {"", NULL, &m_option_type_int} }
#define ARG_FLOAT { .type = {"", NULL, &m_option_type_float} }
+#define ARG_DOUBLE { .type = {"", NULL, &m_option_type_double} }
#define ARG_STRING { .type = {"", NULL, &m_option_type_string} }
#define ARG_CHOICE(c) { .type = {"", NULL, &m_option_type_choice, \
M_CHOICES(c)} }
#define ARG_TIME { .type = {"", NULL, &m_option_type_time} }
-#define OARG_FLOAT(def) { .type = {"", NULL, &m_option_type_float}, \
- .optional = true, .v.f = def }
+#define OARG_DOUBLE(def) { .type = {"", NULL, &m_option_type_double}, \
+ .optional = true, .v.d = def }
#define OARG_INT(def) { .type = {"", NULL, &m_option_type_int}, \
.optional = true, .v.i = def }
#define OARG_CHOICE(def, c) { .type = {"", NULL, &m_option_type_choice, \
@@ -129,7 +130,7 @@ static const mp_cmd_t mp_cmds[] = {
{"exact", 1}, {"1", 1},
{"keyframes", -1}, {"-1", -1})),
}},
- { MP_CMD_SPEED_MULT, "speed_mult", { ARG_FLOAT } },
+ { MP_CMD_SPEED_MULT, "speed_mult", { ARG_DOUBLE } },
{ MP_CMD_QUIT, "quit", { OARG_INT(0) } },
{ MP_CMD_QUIT_WATCH_LATER, "quit_watch_later", },
{ MP_CMD_STOP, "stop", },
@@ -195,12 +196,12 @@ static const mp_cmd_t mp_cmds[] = {
{ MP_CMD_KEYDOWN_EVENTS, "key_down_event", { ARG_INT } },
{ MP_CMD_SET, "set", { ARG_STRING, ARG_STRING } },
{ MP_CMD_GET_PROPERTY, "get_property", { ARG_STRING } },
- { MP_CMD_ADD, "add", { ARG_STRING, OARG_FLOAT(0) } },
+ { MP_CMD_ADD, "add", { ARG_STRING, OARG_DOUBLE(0) } },
{ MP_CMD_CYCLE, "cycle", {
ARG_STRING,
{ .type = {"", NULL, &m_option_type_cycle_dir},
.optional = true,
- .v.f = 1 },
+ .v.d = 1 },
}},
{ MP_CMD_ENABLE_INPUT_SECTION, "enable_section", {
@@ -497,6 +498,9 @@ struct cmd_queue {
};
struct input_ctx {
+ bool using_ar;
+ bool using_cocoa_media_keys;
+
// Autorepeat stuff
short ar_state;
int64_t last_ar;
@@ -572,7 +576,7 @@ static const m_option_t input_config[] = {
{ NULL, NULL, 0, 0, 0, 0, NULL}
};
-static const m_option_t mp_input_opts[] = {
+const m_option_t mp_input_opts[] = {
{ "input", (void *)&input_config, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
OPT_INTRANGE("doubleclick-time", input.doubleclick_time, 0, 0, 1000),
OPT_FLAG("joystick", input.use_joystick, CONF_GLOBAL),
@@ -773,15 +777,15 @@ void mp_input_rm_key_fd(struct input_ctx *ictx, int fd)
static int parse_cycle_dir(const struct m_option *opt, struct bstr name,
struct bstr param, void *dst)
{
- float val;
+ double val;
if (bstrcmp0(param, "up") == 0) {
val = +1;
} else if (bstrcmp0(param, "down") == 0) {
val = -1;
} else {
- return m_option_type_float.parse(opt, name, param, dst);
+ return m_option_type_double.parse(opt, name, param, dst);
}
- *(float *)dst = val;
+ *(double *)dst = val;
return 1;
}
@@ -2069,9 +2073,10 @@ void mp_input_define_section(struct input_ctx *ictx, char *name, char *location,
}
}
-struct input_ctx *mp_input_init(struct input_conf *input_conf,
- bool load_default_conf)
+struct input_ctx *mp_input_init(struct MPOpts *opts)
{
+ struct input_conf *input_conf = &opts->input;
+
struct input_ctx *ictx = talloc_ptrtype(NULL, ictx);
*ictx = (struct input_ctx){
.key_fifo_size = input_conf->key_fifo_size,
@@ -2106,7 +2111,7 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf,
bool config_ok = false;
if (input_conf->config_file)
config_ok = parse_config_file(ictx, input_conf->config_file, true);
- if (!config_ok && load_default_conf) {
+ if (!config_ok && opts->load_config) {
// Try global conf dir
char *file = mp_find_config_file("input.conf");
config_ok = file && parse_config_file(ictx, file, false);
@@ -2148,10 +2153,12 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf,
#ifdef CONFIG_COCOA
if (input_conf->use_ar) {
cocoa_init_apple_remote();
+ ictx->using_ar = true;
}
if (input_conf->use_media_keys) {
cocoa_init_media_keys();
+ ictx->using_cocoa_media_keys = true;
}
#endif
@@ -2186,17 +2193,17 @@ static void clear_queue(struct cmd_queue *queue)
}
}
-void mp_input_uninit(struct input_ctx *ictx, struct input_conf *input_conf)
+void mp_input_uninit(struct input_ctx *ictx)
{
if (!ictx)
return;
#ifdef CONFIG_COCOA
- if (input_conf->use_ar) {
+ if (ictx->using_ar) {
cocoa_uninit_apple_remote();
}
- if (input_conf->use_media_keys) {
+ if (ictx->using_cocoa_media_keys) {
cocoa_uninit_media_keys();
}
#endif
@@ -2215,11 +2222,6 @@ void mp_input_uninit(struct input_ctx *ictx, struct input_conf *input_conf)
talloc_free(ictx);
}
-void mp_input_register_options(m_config_t *cfg)
-{
- m_config_register_options(cfg, mp_input_opts);
-}
-
static int print_key_list(m_option_t *cfg, char *optname, char *optparam)
{
int i;
diff --git a/core/input/input.h b/core/input/input.h
index f4f5621e9f..92e2a32c4f 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -257,14 +257,10 @@ bool mp_input_test_mouse_active(struct input_ctx *ictx, int x, int y);
bool mp_input_test_dragging(struct input_ctx *ictx, int x, int y);
// Initialize the input system
-struct input_conf;
-struct input_ctx *mp_input_init(struct input_conf *input_conf,
- bool load_default_conf);
+struct MPOpts;
+struct input_ctx *mp_input_init(struct MPOpts *opts);
-void mp_input_uninit(struct input_ctx *ictx, struct input_conf *input_conf);
-
-struct m_config;
-void mp_input_register_options(struct m_config *cfg);
+void mp_input_uninit(struct input_ctx *ictx);
// Wake up sleeping input loop from another thread.
void mp_input_wakeup(struct input_ctx *ictx);
diff --git a/core/m_config.c b/core/m_config.c
index b5d1c3fefd..f362b43836 100644
--- a/core/m_config.c
+++ b/core/m_config.c
@@ -34,22 +34,41 @@
#include "core/m_option.h"
#include "core/mp_msg.h"
+// Profiles allow to predefine some sets of options that can then
+// be applied later on with the internal -profile option.
#define MAX_PROFILE_DEPTH 20
-static int parse_include(struct m_config *config, struct bstr param, bool set)
+struct m_profile {
+ struct m_profile *next;
+ char *name;
+ char *desc;
+ int num_opts;
+ // Option/value pair array.
+ char **opts;
+};
+
+// In the file local case, this contains the old global value.
+struct m_opt_backup {
+ struct m_opt_backup *next;
+ struct m_config_option *co;
+ void *backup;
+};
+
+static int parse_include(struct m_config *config, struct bstr param, bool set,
+ int flags)
{
if (param.len == 0)
return M_OPT_MISSING_PARAM;
if (!set)
return 1;
char *filename = bstrdup0(NULL, param);
- config->includefunc(config, filename);
+ config->includefunc(config, filename, flags);
talloc_free(filename);
return 1;
}
static int parse_profile(struct m_config *config, const struct m_option *opt,
- struct bstr name, struct bstr param, bool set)
+ struct bstr name, struct bstr param, bool set, int flags)
{
if (!bstrcmp0(param, "help")) {
struct m_profile *p;
@@ -73,31 +92,31 @@ static int parse_profile(struct m_config *config, const struct m_option *opt,
if (!list || !list[0])
return M_OPT_INVALID;
for (int i = 0; list[i]; i++) {
- struct m_profile *p = m_config_get_profile(config, list[i]);
+ struct m_profile *p = m_config_get_profile0(config, list[i]);
if (!p) {
mp_tmsg(MSGT_CFGPARSER, MSGL_WARN, "Unknown profile '%s'.\n",
list[i]);
r = M_OPT_INVALID;
} else if (set)
- m_config_set_profile(config, p);
+ m_config_set_profile(config, p, flags);
}
m_option_free(opt, &list);
return r;
}
-static int show_profile(struct m_option *opt, char *name, char *param)
+static int show_profile(struct m_config *config, bstr param)
{
- struct m_config *config = opt->priv;
struct m_profile *p;
int i, j;
- if (!param)
+ if (!param.len)
return M_OPT_MISSING_PARAM;
if (!(p = m_config_get_profile(config, param))) {
- mp_tmsg(MSGT_CFGPARSER, MSGL_ERR, "Unknown profile '%s'.\n", param);
+ mp_tmsg(MSGT_CFGPARSER, MSGL_ERR, "Unknown profile '%.*s'.\n",
+ BSTR_P(param));
return M_OPT_EXIT - 1;
}
if (!config->profile_depth)
- mp_tmsg(MSGT_CFGPARSER, MSGL_INFO, "Profile %s: %s\n", param,
+ mp_tmsg(MSGT_CFGPARSER, MSGL_INFO, "Profile %s: %s\n", p->name,
p->desc ? p->desc : "");
config->profile_depth++;
for (i = 0; i < p->num_opts; i++) {
@@ -119,11 +138,11 @@ static int show_profile(struct m_option *opt, char *name, char *param)
continue;
memcpy(tmp, list, l);
tmp[l] = '\0';
- show_profile(opt, name, tmp);
+ show_profile(config, bstr0(tmp));
list = e + 1;
}
if (list[0] != '\0')
- show_profile(opt, name, list);
+ show_profile(config, bstr0(list));
}
}
config->profile_depth--;
@@ -132,9 +151,8 @@ static int show_profile(struct m_option *opt, char *name, char *param)
return M_OPT_EXIT - 1;
}
-static int list_options(struct m_option *opt, char *name, char *param)
+static int list_options(struct m_config *config)
{
- struct m_config *config = opt->priv;
m_config_print_option_list(config);
return M_OPT_EXIT;
}
@@ -153,47 +171,59 @@ static void substruct_write_ptr(void *ptr, void *val)
memcpy(ptr, &val, sizeof(void*));
}
-static void m_config_add_option(struct m_config *config,
- const char *prefix,
- struct m_config_option *parent,
- const struct m_option *arg);
+static struct m_config_option *m_config_add_option(struct m_config *config,
+ const char *prefix,
+ struct m_config_option *parent,
+ const struct m_option *arg);
+
+static void add_options(struct m_config *config,
+ struct m_config_option *parent,
+ const struct m_option *defs);
static int config_destroy(void *p)
{
struct m_config *config = p;
- for (struct m_config_option *copt = config->opts; copt; copt = copt->next) {
- if (copt->alias_owner)
- continue;
- if (copt->opt->type->flags & M_OPT_TYPE_DYNAMIC) {
- m_option_free(copt->opt, copt->data);
- }
- if (copt->global_backup)
- m_option_free(copt->opt, copt->global_backup);
- }
+ m_config_restore_backups(config);
+ for (struct m_config_option *copt = config->opts; copt; copt = copt->next)
+ m_option_free(copt->opt, copt->data);
return 0;
}
-struct m_config *m_config_simple(void *optstruct)
+struct m_config *m_config_new(void *talloc_parent, size_t size,
+ const