0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 12:02:23 +02:00

commands: simplify legacy command-to-property bridge

There are many input commands which are redundant to properties. They
were parsed like normal commands, but set_property_command() in
command.c handled them automatically using the property mechanism. This
still required having the command specifications around, and the code in
command.c was quite messy.

Replace this with a text based replacement mechanism. Some corner cases
are not handled: commands of form "seek_chapter 3 1" are supposed to set
the "chapter" property to 3. This use is probably rare, and doesn't show
up in the default input.conf.

The reason compatibility is kept is because breaking input.conf is quite
annoying, so a minimal effort is made to avoid this. Currently we print
an annoying warning every time a legacy command is used, though.

Also add a compatibility entry for "pt_step", which was removed some
time ago. Variations in whitespace are not handled, but it's good enough
to deal with old input.conf entries.
This commit is contained in:
wm4 2012-09-06 07:19:41 +02:00
parent 0a54f5e741
commit e41378ea71
3 changed files with 63 additions and 188 deletions

112
command.c
View File

@ -1965,115 +1965,6 @@ static int show_property_osd(MPContext *mpctx, const char *pname)
return 0;
}
/**
* Command to property bridge
*
* It is used to handle most commands that just set a property
* and optionally display something on the OSD.
* Two kinds of commands are handled: adjust or toggle.
*
* Adjust commands take 1 or 2 parameters: <value> <abs>
* If <abs> is non-zero the property is set to the given value
* otherwise it is adjusted.
*
* Toggle commands take 0 or 1 parameters. With no parameter
* or a value less than the property minimum it just steps the
* property to its next or previous value respectively.
* Otherwise it sets it to the given value.
*/
/// List of the commands that can be handled by setting a property.
static struct {
/// property name
const char *name;
/// cmd id
int cmd;
/// set/adjust or toggle command
int toggle;
} set_prop_cmd[] = {
// general
{ "loop", MP_CMD_LOOP, 0},
{ "chapter", MP_CMD_SEEK_CHAPTER, 0},
{ "angle", MP_CMD_SWITCH_ANGLE, 0},
{ "pause", MP_CMD_PAUSE, 0},
// audio
{ "volume", MP_CMD_VOLUME, 0},
{ "mute", MP_CMD_MUTE, 1},
{ "audio_delay", MP_CMD_AUDIO_DELAY, 0},
{ "switch_audio", MP_CMD_SWITCH_AUDIO, 1},
{ "balance", MP_CMD_BALANCE, 0},
// video
{ "fullscreen", MP_CMD_VO_FULLSCREEN, 1},
{ "panscan", MP_CMD_PANSCAN, 0},
{ "ontop", MP_CMD_VO_ONTOP, 1},
{ "rootwin", MP_CMD_VO_ROOTWIN, 1},
{ "border", MP_CMD_VO_BORDER, 1},
{ "framedropping", MP_CMD_FRAMEDROPPING, 1},
{ "gamma", MP_CMD_GAMMA, 0},
{ "brightness", MP_CMD_BRIGHTNESS, 0},
{ "contrast", MP_CMD_CONTRAST, 0},
{ "saturation", MP_CMD_SATURATION, 0},
{ "hue", MP_CMD_HUE, 0},
{ "vsync", MP_CMD_SWITCH_VSYNC, 1},
// subs
{ "sub", MP_CMD_SUB_SELECT, 1},
{ "sub_pos", MP_CMD_SUB_POS, 0},
{ "sub_delay", MP_CMD_SUB_DELAY, 0},
{ "sub_visibility", MP_CMD_SUB_VISIBILITY, 1},
{ "sub_forced_only", MP_CMD_SUB_FORCED_ONLY, 1},
{ "sub_scale", MP_CMD_SUB_SCALE, 0},
#ifdef CONFIG_ASS
{ "ass_use_margins", MP_CMD_ASS_USE_MARGINS, 1},
#endif
#ifdef CONFIG_TV
{ "tv_brightness", MP_CMD_TV_SET_BRIGHTNESS, 0},
{ "tv_hue", MP_CMD_TV_SET_HUE, 0},
{ "tv_saturation", MP_CMD_TV_SET_SATURATION, 0},
{ "tv_contrast", MP_CMD_TV_SET_CONTRAST, 0},
#endif
{}
};
/// Handle commands that set a property.
static bool set_property_command(MPContext *mpctx, mp_cmd_t *cmd)
{
int i, r;
m_option_t *prop;
const char *pname;
// look for the command
for (i = 0; set_prop_cmd[i].name; i++)
if (set_prop_cmd[i].cmd == cmd->id)
break;
if (!(pname = set_prop_cmd[i].name))
return 0;
if (mp_property_do(pname, M_PROPERTY_GET_TYPE, &prop, mpctx) <= 0 || !prop)
return 0;
// toggle command
if (set_prop_cmd[i].toggle) {
// set to value
if (cmd->nargs > 0 && cmd->args[0].v.i >= prop->min)
r = mp_property_do(pname, M_PROPERTY_SET, &cmd->args[0].v.i, mpctx);
else if (cmd->nargs > 0)
r = mp_property_do(pname, M_PROPERTY_STEP_DOWN, NULL, mpctx);
else
r = mp_property_do(pname, M_PROPERTY_STEP_UP, NULL, mpctx);
} else if (cmd->args[1].v.i) //set
r = mp_property_do(pname, M_PROPERTY_SET, &cmd->args[0].v, mpctx);
else // adjust
r = mp_property_do(pname, M_PROPERTY_STEP_UP, &cmd->args[0].v, mpctx);
if (r <= 0)
return 1;
show_property_osd(mpctx, pname);
return 1;
}
static const char *property_error_string(int error_value)
{
switch (error_value) {
@ -2176,8 +2067,6 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
sh_video_t *const sh_video = mpctx->sh_video;
int osd_duration = opts->osd_duration;
int case_fallthrough_hack = 0;
if (set_property_command(mpctx, cmd))
goto old_pause_hack; // was handled already
switch (cmd->id) {
case MP_CMD_SEEK: {
mpctx->add_osd_seek_info = true;
@ -2774,7 +2663,6 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
"Received unknown cmd %s\n", cmd->name);
}
old_pause_hack:
switch (cmd->pausing) {
case 1: // "pausing"
pause_player(mpctx);

View File

@ -101,46 +101,21 @@ static const mp_cmd_t mp_cmds[] = {
#endif
{ MP_CMD_SEEK, "seek", { ARG_FLOAT, OARG_INT(0), OARG_INT(0) } },
{ MP_CMD_EDL_MARK, "edl_mark", },
{ MP_CMD_AUDIO_DELAY, "audio_delay", { ARG_FLOAT, OARG_INT(0) } },
{ MP_CMD_SPEED_INCR, "speed_incr", { ARG_FLOAT } },
{ MP_CMD_SPEED_MULT, "speed_mult", { ARG_FLOAT } },
{ MP_CMD_SPEED_SET, "speed_set", { ARG_FLOAT } },
{ MP_CMD_QUIT, "quit", { OARG_INT(0) } },
{ MP_CMD_STOP, "stop", },
{ MP_CMD_PAUSE, "pause", },
{ MP_CMD_FRAME_STEP, "frame_step", },
{ MP_CMD_PLAYLIST_NEXT, "playlist_next", { OARG_INT(0) } },
{ MP_CMD_PLAYLIST_PREV, "playlist_prev", { OARG_INT(0) } },
{ MP_CMD_LOOP, "loop", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_SUB_DELAY, "sub_delay", { ARG_FLOAT, OARG_INT(0) } },
{ MP_CMD_SUB_STEP, "sub_step", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_OSD, "osd", { OARG_INT(-1) } },
{ MP_CMD_OSD_SHOW_TEXT, "osd_show_text", { ARG_STRING, OARG_INT(-1), OARG_INT(0) } },
{ MP_CMD_OSD_SHOW_PROPERTY_TEXT, "osd_show_property_text", { ARG_STRING, OARG_INT(-1), OARG_INT(0) } },
{ MP_CMD_OSD_SHOW_PROGRESSION, "osd_show_progression", },
{ MP_CMD_VOLUME, "volume", { ARG_FLOAT, OARG_INT(0) } },
{ MP_CMD_BALANCE, "balance", { ARG_FLOAT, OARG_INT(0) } },
{ MP_CMD_MIXER_USEMASTER, "use_master", },
{ MP_CMD_MUTE, "mute", { OARG_INT(-1) } },
{ MP_CMD_CONTRAST, "contrast", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_GAMMA, "gamma", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_BRIGHTNESS, "brightness", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_HUE, "hue", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_SATURATION, "saturation", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_FRAMEDROPPING, "frame_drop", { OARG_INT(-1) } },
{ MP_CMD_SUB_POS, "sub_pos", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_SUB_ALIGNMENT, "sub_alignment", { OARG_INT(-1) } },
{ MP_CMD_SUB_VISIBILITY, "sub_visibility", { OARG_INT(-1) } },
{ MP_CMD_SUB_LOAD, "sub_load", { ARG_STRING } },
{ MP_CMD_SUB_SELECT, "vobsub_lang", { OARG_INT(-2) } }, // for compatibility
{ MP_CMD_SUB_SELECT, "sub_select", { OARG_INT(-2) } },
{ MP_CMD_SUB_SCALE, "sub_scale", { ARG_FLOAT, OARG_INT(0) } },
#ifdef CONFIG_ASS
{ MP_CMD_ASS_USE_MARGINS, "ass_use_margins", { OARG_INT(-1) } },
#endif
{ MP_CMD_SWITCH_AUDIO, "switch_audio", { OARG_INT(-1) } },
{ MP_CMD_SWITCH_ANGLE, "switch_angle", { OARG_INT(-1) } },
{ MP_CMD_SWITCH_TITLE, "switch_title", { OARG_INT(-1) } },
#ifdef CONFIG_TV
{ MP_CMD_TV_START_SCAN, "tv_start_scan", },
{ MP_CMD_TV_STEP_CHANNEL, "tv_step_channel", { ARG_INT } },
@ -151,23 +126,12 @@ static const mp_cmd_t mp_cmds[] = {
{ MP_CMD_TV_SET_FREQ, "tv_set_freq", { ARG_FLOAT } },
{ MP_CMD_TV_STEP_FREQ, "tv_step_freq", { ARG_FLOAT } },
{ MP_CMD_TV_SET_NORM, "tv_set_norm", { ARG_STRING } },
{ MP_CMD_TV_SET_BRIGHTNESS, "tv_set_brightness", { ARG_INT, OARG_INT(1) } },
{ MP_CMD_TV_SET_CONTRAST, "tv_set_contrast", { ARG_INT, OARG_INT(1) } },
{ MP_CMD_TV_SET_HUE, "tv_set_hue", { ARG_INT, OARG_INT(1) } },
{ MP_CMD_TV_SET_SATURATION, "tv_set_saturation", { ARG_INT, OARG_INT(1) } },
#endif
{ MP_CMD_SUB_FORCED_ONLY, "forced_subs_only", { OARG_INT(-1) } },
#ifdef CONFIG_DVBIN
{ MP_CMD_DVB_SET_CHANNEL, "dvb_set_channel", { ARG_INT, ARG_INT } },
#endif
{ MP_CMD_SWITCH_RATIO, "switch_ratio", { OARG_FLOAT(0) } },
{ MP_CMD_VO_FULLSCREEN, "vo_fullscreen", { OARG_INT(-1) } },
{ MP_CMD_VO_ONTOP, "vo_ontop", { OARG_INT(-1) } },
{ MP_CMD_VO_ROOTWIN, "vo_rootwin", { OARG_INT(-1) } },
{ MP_CMD_VO_BORDER, "vo_border", { OARG_INT(-1) } },
{ MP_CMD_SCREENSHOT, "screenshot", { OARG_INT(0), OARG_INT(0) } },
{ MP_CMD_PANSCAN, "panscan", { ARG_FLOAT, OARG_INT(0) } },
{ MP_CMD_SWITCH_VSYNC, "switch_vsync", { OARG_INT(0) } },
{ MP_CMD_LOADFILE, "loadfile", { ARG_STRING, OARG_INT(0) } },
{ MP_CMD_LOADLIST, "loadlist", { ARG_STRING, OARG_INT(0) } },
{ MP_CMD_PLAYLIST_CLEAR, "playlist_clear", },
@ -180,7 +144,6 @@ static const mp_cmd_t mp_cmds[] = {
{ MP_CMD_STEP_PROPERTY, "step_property", { ARG_STRING, OARG_FLOAT(0), OARG_INT(0) } },
{ MP_CMD_STEP_PROPERTY_OSD, "step_property_osd", { ARG_STRING, OARG_FLOAT(0), OARG_INT(0) } },
{ MP_CMD_SEEK_CHAPTER, "seek_chapter", { ARG_INT, OARG_INT(0) } },
{ MP_CMD_SET_MOUSE_POS, "set_mouse_pos", { ARG_INT, ARG_INT } },
{ MP_CMD_AF_SWITCH, "af_switch", { ARG_STRING } },
@ -197,6 +160,50 @@ static const mp_cmd_t mp_cmds[] = {
{0}
};
// Map legacy commands to proper commands
struct legacy_cmd {
const char *old, *new;
};
#define LEGACY_STEP(old) {old, "step_property_osd " old}
static const struct legacy_cmd legacy_cmds[] = {
LEGACY_STEP("loop"),
{"seek_chapter", "step_property_osd chapter"},
{"switch_angle", "step_property_osd angle"},
LEGACY_STEP("pause"),
LEGACY_STEP("volume"),
LEGACY_STEP("mute"),
LEGACY_STEP("audio_delay"),
LEGACY_STEP("switch_audio"),
LEGACY_STEP("balance"),
{"vo_fullscreen", "step_property fullscreen"},
LEGACY_STEP("panscan"),
{"vo_ontop", "step_property_osd ontop"},
{"vo_rootwin", "step_property_osd rootwin"},
{"vo_border", "step_property_osd border"},
{"frame_drop", "step_property_osd framedropping"},
LEGACY_STEP("gamma"),
LEGACY_STEP("brightness"),
LEGACY_STEP("contrast"),
LEGACY_STEP("saturation"),
LEGACY_STEP("hue"),
{"switch_vsync", "step_property_osd vsync"},
{"sub_select", "step_property_osd sub"},
LEGACY_STEP("sub_pos"),
LEGACY_STEP("sub_delay"),
LEGACY_STEP("sub_visibility"),
{"forced_subs_only", "step_property_osd sub_forced_only"},
LEGACY_STEP("sub_scale"),
LEGACY_STEP("ass_use_margins"),
{"tv_set_brightness", "tv_brightness"},
{"tv_set_hue", "tv_hue"},
{"tv_set_saturation", "tv_saturation"},
{"tv_set_contrast", "tv_contrast"},
{"pt_step 1", "playlist_next"},
{"pt_step -1", "playlist_prev"},
{0}
};
/// The names of the keys as used in input.conf
/// If you add some new keys, you also need to add them here
@ -685,6 +692,8 @@ mp_cmd_t *mp_input_parse_cmd(char *str)
int pausing = 0;
char *ptr;
const mp_cmd_t *cmd_def;
mp_cmd_t *cmd = NULL;
void *tmp = NULL;
// Ignore heading spaces.
while (str[0] == ' ' || str[0] == '\t')
@ -704,6 +713,18 @@ mp_cmd_t *mp_input_parse_cmd(char *str)
str = &str[19];
}
for (const struct legacy_cmd *entry = legacy_cmds; entry->old; entry++) {
size_t old_len = strlen(entry->old);
if (strncasecmp(entry->old, str, old_len) == 0) {
mp_tmsg(MSGT_INPUT, MSGL_WARN, "Warning: command '%s' is "
"deprecated, replaced with '%s'. Fix your input.conf!\n",
entry->old, entry->new);
str = talloc_asprintf(NULL, "%s%s", entry->new, str + old_len);
tmp = str;
break;
}
}
ptr = str + strcspn(str, "\t ");
if (*ptr != 0)
l = ptr - str;
@ -711,7 +732,7 @@ mp_cmd_t *mp_input_parse_cmd(char *str)
l = strlen(str);
if (l == 0)
return NULL;
goto error;
for (i = 0; mp_cmds[i].name != NULL; i++) {
if (strncasecmp(mp_cmds[i].name, str, l) == 0)
@ -719,11 +740,11 @@ mp_cmd_t *mp_input_parse_cmd(char *str)
}
if (mp_cmds[i].name == NULL)
return NULL;
goto error;
cmd_def = &mp_cmds[i];
mp_cmd_t *cmd = talloc_ptrtype(NULL, cmd);
cmd = talloc_ptrtype(NULL, cmd);
*cmd = (mp_cmd_t){
.id = cmd_def->id,
.name = talloc_strdup(cmd, cmd_def->name),
@ -815,10 +836,12 @@ mp_cmd_t *mp_input_parse_cmd(char *str)
if (i < MP_CMD_MAX_ARGS)
cmd->args[i].type = 0;
talloc_free(tmp);
return cmd;
error:
mp_cmd_free(cmd);
talloc_free(tmp);
return NULL;
}

View File

@ -24,68 +24,38 @@
// All command IDs
enum mp_command_type {
MP_CMD_SEEK,
MP_CMD_AUDIO_DELAY,
MP_CMD_QUIT,
MP_CMD_PAUSE,
MP_CMD_GRAB_FRAMES, // deprecated: was a no-op command for years
MP_CMD_PLAYLIST_NEXT,
MP_CMD_PLAYLIST_PREV,
MP_CMD_SUB_DELAY,
MP_CMD_OSD,
MP_CMD_VOLUME,
MP_CMD_MIXER_USEMASTER,
MP_CMD_CONTRAST,
MP_CMD_BRIGHTNESS,
MP_CMD_HUE,
MP_CMD_SATURATION,
MP_CMD_FRAMEDROPPING,
MP_CMD_TV_STEP_CHANNEL,
MP_CMD_TV_STEP_NORM,
MP_CMD_TV_STEP_CHANNEL_LIST,
MP_CMD_VO_FULLSCREEN,
MP_CMD_SUB_POS,
MP_CMD_SCREENSHOT,
MP_CMD_PANSCAN,
MP_CMD_MUTE,
MP_CMD_LOADFILE,
MP_CMD_LOADLIST,
MP_CMD_PLAYLIST_CLEAR,
MP_CMD_GAMMA,
MP_CMD_SUB_VISIBILITY,
MP_CMD_VOBSUB_LANG, // deprecated: combined with SUB_SELECT
MP_CMD_SUB_STEP,
MP_CMD_TV_SET_CHANNEL,
MP_CMD_EDL_MARK,
MP_CMD_SUB_ALIGNMENT,
MP_CMD_TV_LAST_CHANNEL,
MP_CMD_OSD_SHOW_TEXT,
MP_CMD_TV_SET_FREQ,
MP_CMD_TV_SET_NORM,
MP_CMD_TV_SET_BRIGHTNESS,
MP_CMD_TV_SET_CONTRAST,
MP_CMD_TV_SET_HUE,
MP_CMD_TV_SET_SATURATION,
MP_CMD_SUB_FORCED_ONLY,
MP_CMD_VO_ONTOP,
MP_CMD_SUB_SELECT,
MP_CMD_VO_ROOTWIN,
MP_CMD_SWITCH_VSYNC,
MP_CMD_SWITCH_RATIO,
MP_CMD_FRAME_STEP,
MP_CMD_SPEED_INCR,
MP_CMD_SPEED_MULT,
MP_CMD_SPEED_SET,
MP_CMD_RUN,
MP_CMD_SWITCH_AUDIO,
MP_CMD_SUB_LOAD,
MP_CMD_KEYDOWN_EVENTS,
MP_CMD_VO_BORDER,
MP_CMD_SET_PROPERTY,
MP_CMD_SET_PROPERTY_OSD,
MP_CMD_GET_PROPERTY,
MP_CMD_OSD_SHOW_PROPERTY_TEXT,
MP_CMD_OSD_SHOW_PROGRESSION,
MP_CMD_SEEK_CHAPTER,
MP_CMD_RADIO_STEP_CHANNEL,
MP_CMD_RADIO_SET_CHANNEL,
MP_CMD_RADIO_SET_FREQ,
@ -94,13 +64,7 @@ enum mp_command_type {
MP_CMD_STEP_PROPERTY_OSD,
MP_CMD_RADIO_STEP_FREQ,
MP_CMD_TV_STEP_FREQ,
MP_CMD_LOOP,
MP_CMD_BALANCE,
MP_CMD_SUB_SCALE,
MP_CMD_TV_START_SCAN,
MP_CMD_SWITCH_ANGLE,
MP_CMD_ASS_USE_MARGINS,
MP_CMD_SWITCH_TITLE,
MP_CMD_STOP,
/// DVB commands