diff options
author | wm4 <wm4@nowhere> | 2018-05-17 20:10:39 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2018-05-24 19:56:34 +0200 |
commit | 332907e1d7225ae39565d462aac5c45c3a5cad97 (patch) | |
tree | 5c4ab4f6e8d5bb262b3cb9cdeee724eff7c4a890 /player/command.c | |
parent | d36b85cfdf4714a0498aec2a1f548ce0467e4fe3 (diff) | |
download | mpv-332907e1d7225ae39565d462aac5c45c3a5cad97.tar.bz2 mpv-332907e1d7225ae39565d462aac5c45c3a5cad97.tar.xz |
command: give named arguments to almost all commands
Before this change, only 1 command or so had named arguments. There is
no reason why other commands can't have them, except that it's a bit of
work to add them.
Commands with variable number of arguments are inherently incompatible
to named arguments, such as the "run" command. They still have dummy
names, but obviously you can't assign multiple values to a single named
argument (unless the argument has an array type, which would be
something different). For now, disallow using named argument APIs with
these commands. This might change later.
2 commands are adjusted to not need a separate default value by changing
flag constants. (The numeric values are C only and can't be set by
users.)
Make the command syntax in the manpage more consistent. Now none of the
allowed choice/flag names are in the command header, and all arguments
are shown with their proper name and quoted with <...>.
Some places in the manpage and the client.h doxygen are updated to
reflect that most commands support named arguments. In addition, try to
improve the documentation of the syntax and need for escaping etc. as
well.
(Or actually most uses of the word "argument" should be "parameter".)
Diffstat (limited to 'player/command.c')
-rw-r--r-- | player/command.c | 395 |
1 files changed, 225 insertions, 170 deletions
diff --git a/player/command.c b/player/command.c index ffe9683adb..9c6bce6aa1 100644 --- a/player/command.c +++ b/player/command.c @@ -5623,7 +5623,7 @@ static void cmd_rescan_external_files(void *p) } autoload_external_files(mpctx); - if (cmd->args[0].v.i && mpctx->playback_initialized) { + if (!cmd->args[0].v.i && mpctx->playback_initialized) { // somewhat fuzzy and not ideal struct track *a = select_default_track(mpctx, 0, STREAM_AUDIO); if (a && a->is_external) @@ -5752,7 +5752,7 @@ static void cmd_define_input_section(void *p) struct mp_cmd_ctx *cmd = p; struct MPContext *mpctx = cmd->mpctx; mp_input_define_section(mpctx->input, cmd->args[0].v.s, "<api>", - cmd->args[1].v.s, !!cmd->args[2].v.i, + cmd->args[1].v.s, !cmd->args[2].v.i, cmd->cmd->sender); } @@ -6005,263 +6005,318 @@ static void cmd_load_script(void *p) cmd->success = false; } -// This does not specify the real destination of the command parameter values, -// it just provides a dummy for the OPT_ macros. -#define OPT_BASE_STRUCT struct mp_cmd_arg -#define ARG(t) "", v. t - /* This array defines all known commands. - * The first field is an id used to recognize the command. - * The second is the command name used in slave mode and input.conf. - * Then comes the definition of each argument, first mandatory arguments - * (ARG_INT, ARG_FLOAT, ARG_STRING) if any, then optional arguments - * (OARG_INT(default), etc) if any. The command will be given the default - * argument value if the user didn't give enough arguments to specify it. - * A command can take a maximum of MP_CMD_DEF_MAX_ARGS arguments, or more - * if the command uses varargs. + * The first field the command name used in libmpv and input.conf. + * The second field is the handler function (see mp_cmd_def.handler and + * run_command()). + * Then comes the definition of each argument. They are defined like options, + * except that the result is parsed into mp_cmd.args[] (thus the option variable + * is a field in the mp_cmd_arg union field). Arguments are optional if either + * defval is set (usually via OPTDEF_ macros), or the MP_CMD_OPT_ARG flag is + * set, or if it's the last argument and .vararg is set. If .vararg is set, the + * command has an arbitrary number of arguments, all using the type indicated by + * the last argument (they are appended to mp_cmd.args[] starting at the last + * argument's index). + * Arguments have named, which can be used by named argument functions, e.g. in + * Lua with mp.command_native(). */ -#define ARG_INT OPT_INT(ARG(i), 0) -#define ARG_FLOAT OPT_FLOAT(ARG(f), 0) -#define ARG_DOUBLE OPT_DOUBLE(ARG(d), 0) -#define ARG_STRING OPT_STRING(ARG(s), 0) -#define ARG_CHOICE(c) OPT_CHOICE(ARG(i), 0, c) -#define ARG_CHOICE_OR_INT(...) OPT_CHOICE_OR_INT(ARG(i), 0, __VA_ARGS__) -#define ARG_TIME OPT_TIME(ARG(d), 0) -#define OARG_DOUBLE(def) OPT_DOUBLE(ARG(d), 0, OPTDEF_DOUBLE(def)) -#define OARG_INT(def) OPT_INT(ARG(i), 0, OPTDEF_INT(def)) -#define OARG_CHOICE(def, c) OPT_CHOICE(ARG(i), 0, c, OPTDEF_INT(def)) -#define OARG_FLAGS(def, c) OPT_FLAGS(ARG(i), 0, c, OPTDEF_INT(def)) -#define OARG_STRING(def) OPT_STRING(ARG(s), 0, OPTDEF_STR(def)) - -#define OARG_CYCLEDIR(def) OPT_CYCLEDIR(ARG(d), 0, OPTDEF_DOUBLE(def)) +// This does not specify the real destination of the command parameter values, +// it just provides a dummy for the OPT_ macros. The real destination is an +// array item in mp_cmd.args[], using the index of the option definition. +#define OPT_BASE_STRUCT struct mp_cmd_arg const struct mp_cmd_def mp_cmds[] = { { "ignore", cmd_ignore, .is_ignore = true }, - { "seek", cmd_seek, { - ARG_TIME, - OARG_FLAGS(4|0, ({"relative", 4|0}, {"-", 4|0}, - {"absolute-percent", 4|1}, - {"absolute", 4|2}, - {"relative-percent", 4|3}, - {"keyframes", 32|8}, - {"exact", 32|16})), - // backwards compatibility only - OARG_CHOICE(0, ({"unused", 0}, {"default-precise", 0}, + { "seek", cmd_seek, + { + OPT_TIME("target", v.d, 0), + OPT_FLAGS("flags", v.i, 0, + ({"relative", 4|0}, {"-", 4|0}, + {"absolute-percent", 4|1}, + {"absolute", 4|2}, + {"relative-percent", 4|3}, + {"keyframes", 32|8}, + {"exact", 32|16}), + OPTDEF_INT(4|0)), + // backwards compatibility only + OPT_CHOICE("legacy", v.i, MP_CMD_OPT_ARG, + ({"unused", 0}, {"default-precise", 0}, {"keyframes", 32|8}, {"exact", 32|16})), }, .allow_auto_repeat = true, .scalable = true, }, - { "revert-seek", cmd_revert_seek, { - OARG_FLAGS(0, ({"mark", 1})), - }}, - { "quit", cmd_quit, { OARG_INT(0) }, + { "revert-seek", cmd_revert_seek, + {OPT_FLAGS("flags", v.i, MP_CMD_OPT_ARG, ({"mark", 1}))}, + }, + { "quit", cmd_quit, { OPT_INT("code", v.i, MP_CMD_OPT_ARG) }, .priv = &(const bool){0}, .is_abort = true }, - { "quit-watch-later", cmd_quit, { OARG_INT(0) }, + { "quit-watch-later", cmd_quit, { OPT_INT("code", v.i, MP_CMD_OPT_ARG) }, .priv = &(const bool){1}, .is_abort = true }, { "stop", cmd_stop, .is_abort = true }, { "frame-step", cmd_frame_step, .allow_auto_repeat = true, .on_updown = true }, { "frame-back-step", cmd_frame_back_step, .allow_auto_repeat = true }, - { "playlist-next", cmd_playlist_next_prev, { - OARG_CHOICE(0, ({"weak", 0}, - {"force", 1})), + { "playlist-next", cmd_playlist_next_prev, + { + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, ({"weak", 0}, + {"force", 1})), }, .is_soft_abort = true, .priv = &(const int){1}, }, - { "playlist-prev", cmd_playlist_next_prev, { - OARG_CHOICE(0, ({"weak", 0}, - {"force", 1})), + { "playlist-prev", cmd_playlist_next_prev, + { + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, ({"weak", 0}, + {"force", 1})), }, .is_soft_abort = true, .priv = &(const int){-1}, }, { "playlist-shuffle", cmd_playlist_shuffle, }, - { "sub-step", cmd_sub_step_seek, { ARG_INT }, .allow_auto_repeat = true, - .priv = &(const bool){true} }, - { "sub-seek", cmd_sub_step_seek, { ARG_INT }, .allow_auto_repeat = true, - .priv = &(const bool){false} }, - { "print-text", cmd_print_text, { ARG_STRING }, .allow_auto_repeat = true }, - { "show-text", cmd_show_text, { ARG_STRING, OARG_INT(-1), OARG_INT(0) }, + { "sub-step", cmd_sub_step_seek, { OPT_INT("skip", v.i, 0) }, + .allow_auto_repeat = true, .priv = &(const bool){true} }, + { "sub-seek", cmd_sub_step_seek, { OPT_INT("skip", v.i, 0) }, + .allow_auto_repeat = true, .priv = &(const bool){false} }, + { "print-text", cmd_print_text, { OPT_STRING("text", v.s, 0) }, + .allow_auto_repeat = true }, + { "show-text", cmd_show_text, { OPT_STRING("text", v.s, 0), + OPT_INT("duration", v.i, 0, OPTDEF_INT(-1)), + OPT_INT("level", v.i, MP_CMD_OPT_ARG), }, .allow_auto_repeat = true}, - { "expand-text", cmd_expand_text, { ARG_STRING } }, + { "expand-text", cmd_expand_text, { OPT_STRING("text", v.s, 0) } }, { "show-progress", cmd_show_progress, .allow_auto_repeat = true}, - { "sub-add", cmd_track_add, { - ARG_STRING, - OARG_CHOICE(0, ({"select", 0}, {"auto", 1}, {"cached", 2})), - OARG_STRING(""), OARG_STRING(""), + + { "sub-add", cmd_track_add, + { + OPT_STRING("url", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"select", 0}, {"auto", 1}, {"cached", 2})), + OPT_STRING("title", v.s, MP_CMD_OPT_ARG), + OPT_STRING("lang", v.s, MP_CMD_OPT_ARG), }, .priv = &(const int){STREAM_SUB}, .spawn_thread = true, }, - { "sub-remove", cmd_track_remove, { OARG_INT(-1) }, + { "audio-add", cmd_track_add, + { + OPT_STRING("url", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"select", 0}, {"auto", 1}, {"cached", 2})), + OPT_STRING("title", v.s, MP_CMD_OPT_ARG), + OPT_STRING("lang", v.s, MP_CMD_OPT_ARG), + }, + .priv = &(const int){STREAM_AUDIO}, + .spawn_thread = true, + }, + + { "sub-remove", cmd_track_remove, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) }, .priv = &(const int){STREAM_SUB}, }, - { "sub-reload", cmd_track_reload, { OARG_INT(-1) }, + { "audio-remove", cmd_track_remove, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) }, + .priv = &(const int){STREAM_AUDIO}, }, + + { "sub-reload", cmd_track_reload, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) }, .priv = &(const int){STREAM_SUB}, .spawn_thread = true, }, + { "audio-reload", cmd_track_reload, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) }, + .priv = &(const int){STREAM_AUDIO}, + .spawn_thread = true, + }, + + { "rescan-external-files", cmd_rescan_external_files, + { + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"keep-selection", 1}, + {"reselect", 0})), + }, + .spawn_thread = true, + }, { "tv-last-channel", cmd_tv_last_channel, }, - { "screenshot", cmd_screenshot, { - OARG_FLAGS(4|2, ({"video", 4|0}, {"-", 4|0}, - {"window", 4|1}, - {"subtitles", 4|2}, - {"each-frame", 8})), - // backwards compatibility - OARG_CHOICE(0, ({"unused", 0}, {"single", 0}, - {"each-frame", 8})), + { "screenshot", cmd_screenshot, + { + OPT_FLAGS("flags", v.i, 0, + ({"video", 4|0}, {"-", 4|0}, + {"window", 4|1}, + {"subtitles", 4|2}, + {"each-frame", 8}), + OPTDEF_INT(4|2)), + // backwards compatibility + OPT_CHOICE("legacy", v.i, MP_CMD_OPT_ARG, + ({"unused", 0}, {"single", 0}, + {"each-frame", 8})), }, .spawn_thread = true, }, - { "screenshot-to-file", cmd_screenshot_to_file, { - ARG_STRING, - OARG_CHOICE(2, ({"video", 0}, + { "screenshot-to-file", cmd_screenshot_to_file, + { + OPT_STRING("filename", v.s, 0), + OPT_CHOICE("flags", v.i, 0, + ({"video", 0}, {"window", 1}, - {"subtitles", 2})), + {"subtitles", 2}), + OPTDEF_INT(2)), }, .spawn_thread = true, }, - { "screenshot-raw", cmd_screenshot_raw, { - OARG_CHOICE(2, ({"video", 0}, + { "screenshot-raw", cmd_screenshot_raw, + { + OPT_CHOICE("flags", v.i, 0, + ({"video", 0}, {"window", 1}, - {"subtitles", 2})), - }}, - { "loadfile", cmd_loadfile, { - ARG_STRING, - OARG_CHOICE(0, ({"replace", 0}, + {"subtitles", 2}), + OPTDEF_INT(2)), + }, + }, + { "loadfile", cmd_loadfile, + { + OPT_STRING("url", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"replace", 0}, {"append", 1}, {"append-play", 2})), - OPT_KEYVALUELIST(ARG(str_list), MP_CMD_OPT_ARG), - }}, - { "loadlist", cmd_loadlist, { - ARG_STRING, - OARG_CHOICE(0, ({"replace", 0}, - {"append", 1})), - }}, + OPT_KEYVALUELIST("options", v.str_list, MP_CMD_OPT_ARG), + }, + }, + { "loadlist", cmd_loadlist, { OPT_STRING("url", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"replace", 0}, {"append", 1})), }}, { "playlist-clear", cmd_playlist_clear }, - { "playlist-remove", cmd_playlist_remove, { - ARG_CHOICE_OR_INT(0, INT_MAX, ({"current", -1})), - }}, - { "playlist-move", cmd_playlist_move, { ARG_INT, ARG_INT } }, - { "run", cmd_run, { ARG_STRING, ARG_STRING }, .vararg = true }, + { "playlist-remove", cmd_playlist_remove, + {OPT_CHOICE_OR_INT("index", v.i, MP_CMD_OPT_ARG, 0, INT_MAX, + ({"current", -1}))}, + }, + { "playlist-move", cmd_playlist_move, { OPT_INT("index1", v.i, 0), + OPT_INT("index2", v.i, 0), }}, + { "run", cmd_run, { OPT_STRING("command", v.s, 0), + OPT_STRING("args", v.s, 0), }, + .vararg = true, + }, { "subprocess", cmd_subprocess, { OPT_STRINGLIST("args", v.str_list, 0), OPT_FLAG("playback_only", v.i, 0, OPTDEF_INT(1)), OPT_BYTE_SIZE("capture_size", v.i64, 0, 0, INT_MAX, OPTDEF_INT64(64 * 1024 * 1024)), - OPT_FLAG("capture_stdout", v.i, 0, OPTDEF_INT(0)), - OPT_FLAG("capture_stderr", v.i, 0, OPTDEF_INT(0)), + OPT_FLAG("capture_stdout", v.i, MP_CMD_OPT_ARG), + OPT_FLAG("capture_stderr", v.i, MP_CMD_OPT_ARG), }, .spawn_thread = true, .can_abort = true, }, - { "set", cmd_set, { ARG_STRING, ARG_STRING } }, - { "change-list", cmd_change_list, { ARG_STRING, ARG_STRING, ARG_STRING } }, - { "add", cmd_add_cycle, { ARG_STRING, OARG_DOUBLE(1) }, + { "set", cmd_set, {OPT_STRING("name", v.s, 0), OPT_STRING("value", v.s, 0)}}, + { "change-list", cmd_change_list, { OPT_STRING("name", v.s, 0), + OPT_STRING("operation", v.s, 0), + OPT_STRING("value", v.s, 0) }}, + { "add", cmd_add_cycle, { OPT_STRING("name", v.s, 0), + OPT_DOUBLE("value", v.d, 0, OPTDEF_DOUBLE(1)), }, .allow_auto_repeat = true, .scalable = true, }, - { "cycle", cmd_add_cycle, { - ARG_STRING, - OARG_CYCLEDIR(1), - }, + { "cycle", cmd_add_cycle, { OPT_STRING("name", v.s, 0), + OPT_CYCLEDIR("value", v.d, 0, OPTDEF_DOUBLE(1)), }, .allow_auto_repeat = true, .scalable = true, .priv = "", }, - { "multiply", cmd_multiply, { ARG_STRING, ARG_DOUBLE }, + { "multiply", cmd_multiply, { OPT_STRING("name", v.s, 0), + OPT_DOUBLE("value", v.d, 0)}, .allow_auto_repeat = true}, - { "cycle-values", cmd_cycle_values, { ARG_STRING, ARG_STRING, ARG_STRING }, + { "cycle-values", cmd_cycle_values, { OPT_STRING("arg0", v.s, 0), + OPT_STRING("arg1", v.s, 0), + OPT_STRING("argN", v.s, 0), }, .vararg = true}, - { "enable-section", cmd_enable_input_section, { - ARG_STRING, - OARG_FLAGS(0, ({"default", 0}, + { "enable-section", cmd_enable_input_section, + { + OPT_STRING("name", v.s, 0), + OPT_FLAGS("flags", v.i, MP_CMD_OPT_ARG, + ({"default", 0}, {"exclusive", MP_INPUT_EXCLUSIVE}, {"allow-hide-cursor", MP_INPUT_ALLOW_HIDE_CURSOR}, {"allow-vo-dragging", MP_INPUT_ALLOW_VO_DRAGGING})), - }}, - { "disable-section", cmd_disable_input_section, { ARG_STRING } }, - { "define-section", cmd_define_input_section, { - ARG_STRING, - ARG_STRING, - OARG_CHOICE(1, ({"default", 1}, - {"force", 0})), - }}, + } + }, + { "disable-section", cmd_disable_input_section, + {OPT_STRING("name", v.s, 0) }}, + { "define-section", cmd_define_input_section, + { + OPT_STRING("name", v.s, 0), + OPT_STRING("contents", v.s, 0), + OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, + ({"default", 0}, {"force", 1})), + }, + }, { "ab-loop", cmd_ab_loop }, { "drop-buffers", cmd_drop_buffers, }, - { "af", cmd_filter, { ARG_STRING, ARG_STRING }, - .priv = &(const int){STREAM_AUDIO}, }, - { "af-command", cmd_filter_command, { ARG_STRING, ARG_STRING, ARG_STRING }, - .priv = &(const int){STREAM_AUDIO}, }, - { "ao-reload", cmd_ao_reload }, + { "af", cmd_filter, { OPT_STRING("operation", v.s, 0), + OPT_STRING("value", v.s, 0), }, + .priv = &(const int){STREAM_AUDIO} }, + { "vf", cmd_filter, { OPT_STRING("operation", v.s, 0), + OPT_STRING("value", v.s, 0), }, + .priv = &(const int){STREAM_VIDEO} }, + + { "af-command", cmd_filter_command, { OPT_STRING("label", v.s, 0), + OPT_STRING("command", v.s, 0), + OPT_STRING("argument", v.s, 0), }, + .priv = &(const int){STREAM_AUDIO} }, + { "vf-command", cmd_filter_command, { OPT_STRING("label", v.s, 0), + OPT_STRING("command", v.s, 0), + OPT_STRING("argument", v.s, 0), }, + .priv = &(const int){STREAM_VIDEO} }, - { "vf", cmd_filter, { ARG_STRING, ARG_STRING }, - .priv = &(const int){STREAM_VIDEO}, }, - { "vf-command", cmd_filter_command, { ARG_STRING, ARG_STRING, ARG_STRING }, - .priv = &(const int){STREAM_VIDEO}, }, + { "ao-reload", cmd_ao_reload }, - { "script-binding", cmd_script_binding, { ARG_STRING }, + { "script-binding", cmd_script_binding, { OPT_STRING("name", v.s, 0) }, .allow_auto_repeat = true, .on_updown = true}, - { "script-message", cmd_script_message, { ARG_STRING }, .vararg = true }, - { "script-message-to", cmd_script_message_to, { ARG_STRING, ARG_STRING }, + { "script-message", cmd_script_message, { OPT_STRING("args", v.s, 0) }, + .vararg = true }, + { "script-message-to", cmd_script_message_to, { OPT_STRING("target", v.s, 0), + OPT_STRING("args", v.s, 0) }, .vararg = true }, - { "overlay-add", cmd_overlay_add, - { ARG_INT, ARG_INT, ARG_INT, ARG_STRING, ARG_INT, ARG_STRING, ARG_INT, - ARG_INT, ARG_INT }}, - { "overlay-remove", cmd_overlay_remove, { ARG_INT } }, + { "overlay-add", cmd_overlay_add, { OPT_INT("id", v.i, 0), + OPT_INT("x", v.i, 0), + OPT_INT("y", v.i, 0), + OPT_STRING("file", v.s, 0), + OPT_INT("offset", v.i, 0), + OPT_STRING("fmt", v.s, 0), + OPT_INT("w", v.i, 0), + OPT_INT("h", v.i, 0), + OPT_INT("stride", v.i, 0), }}, + { "overlay-remove", cmd_overlay_remove, { OPT_INT("id", v.i, 0) } }, { "write-watch-later-config", cmd_write_watch_later_config }, - { "hook-add", cmd_hook_add, { ARG_STRING, ARG_INT, ARG_INT } }, - { "hook-ack", cmd_hook_ack, { ARG_INT } }, - - { "mouse", cmd_mouse, { - ARG_INT, ARG_INT, // coordinate (x, y) - OARG_INT(-1), // button number - OARG_CHOICE(0, ({"single", 0}, - {"double", 1})), - }}, - { "keypress", cmd_key, { ARG_STRING }, .priv = &(const int){0}}, - { "keydown", cmd_key, { ARG_STRING }, .priv = &(const int){MP_KEY_STATE_DOWN}}, - { "keyup", cmd_key, { OARG_STRING("") }, .priv = &(const int){MP_KEY_STATE_UP}}, - - { "audio-add", cmd_track_add, { - ARG_STRING, - OARG_CHOICE(0, ({"select", 0}, {"auto", 1}, {"cached", 2})), - OARG_STRING(""), OARG_STRING(""), - }, - .priv = &(const int){STREAM_AUDIO}, - .spawn_thread = true, - }, - { "audio-remove", cmd_track_remove, { OARG_INT(-1) }, - .priv = &(const int){STREAM_AUDIO}, }, - { "audio-reload", cmd_track_reload, { OARG_INT(-1) }, - .priv = &(const int){STREAM_AUDIO}, - .spawn_thread = true, - }, - - { "rescan-external-files", cmd_rescan_external_files, { - OARG_CHOICE(1, ({"keep-selection", 0}, - {"reselect", 1})), - }, - .spawn_thread = true, - }, - - { "apply-profile", cmd_apply_profile, {ARG_STRING } }, - - { "load-script", cmd_load_script, {ARG_STRING} }, + { "hook-add", cmd_hook_add, { OPT_STRING("arg0", v.s, 0), + OPT_INT("arg1", v.i, 0), + OPT_INT("arg2", v.i, 0) }}, + { "hook-ack", cmd_hook_ack, { OPT_INT("arg0", v.i, 0) }}, + + { "mouse", cmd_mouse, { OPT_INT("x", v.i, 0), + OPT_INT("y", v.i, 0), + OPT_INT("button", v.i, 0, OPTDEF_INT(-1)), + OPT_CHOICE("mode", v.i, MP_CMD_OPT_ARG, + ({"single", 0}, {"double", 1})), }}, + { "keypress", cmd_key, { OPT_STRING("name", v.s, 0) }, + .priv = &(const int){0}}, + { "keydown", cmd_key, { OPT_STRING("name", v.s, 0) }, + .priv = &(const int){MP_KEY_STATE_DOWN}}, + { "keyup", cmd_key, { OPT_STRING("name", v.s, MP_CMD_OPT_ARG) }, + .priv = &(const int){MP_KEY_STATE_UP}}, + + { "apply-profile", cmd_apply_profile, {OPT_STRING("name", v.s, 0)} }, + + { "load-script", cmd_load_script, {OPT_STRING("filename", v.s, 0)} }, {0} }; |