From f0649f13d698eb6aeffeaacd6801b666c4366caf Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Wed, 15 Dec 2010 01:09:47 +0200 Subject: core: add support for precise non-keyframe-limited seeks Add support for seeking to an arbitrary non-keyframe position by decoding video starting from the previous keyframe. Whether to use this functionality when seeking is controlled by the new option -hr-seek and a new third argument to the "seek" command. The default is to use it for absolute seeks (like chapter seeks) but not for relative ones. Because there's currently no support for cutting encoded audio some desync is expected if encoded audio passthrough is used. Currently precise seeks always go to the first frame with timestamp equal to or greater than the target position; there's no support for "matching or earlier" backwards seeks at frame level. --- input/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'input/input.c') diff --git a/input/input.c b/input/input.c index c08f3d49f0..72725a5409 100644 --- a/input/input.c +++ b/input/input.c @@ -86,7 +86,7 @@ static const mp_cmd_t mp_cmds[] = { { MP_CMD_RADIO_SET_FREQ, "radio_set_freq", 1, { {MP_CMD_ARG_FLOAT,{0}}, {-1,{0}} } }, { MP_CMD_RADIO_STEP_FREQ, "radio_step_freq", 1, { {MP_CMD_ARG_FLOAT,{0}}, {-1,{0}} } }, #endif - { MP_CMD_SEEK, "seek", 1, { {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_SEEK, "seek", 1, { {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, { MP_CMD_EDL_MARK, "edl_mark", 0, { {-1,{0}} } }, { MP_CMD_AUDIO_DELAY, "audio_delay", 1, { {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, { MP_CMD_SPEED_INCR, "speed_incr", 1, { {MP_CMD_ARG_FLOAT,{0}}, {-1,{0}} } }, -- cgit v1.2.3 From 67fd58d6f01ad84387421e2fc861c28dcf5c4f3c Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sun, 19 Dec 2010 12:12:20 +0200 Subject: input: support bindings with modifier keys for X input Add support for binding commands to modifier+key combinations like "Shift+Left" or "Ctrl+Alt+x", and support reading such combinations from the output window of X VOs. The recognized modifier names are Shift, Ctrl, Alt and Meta. Any combination of those and then a non-modifier key name, separated by '+', is accepted as a key name in input.conf. For non-special keys that produce characters shift is ignored as a modifier. For example "A" is handled as a key without modifiers even if you use shift to write the capital letter; 'a' vs 'A' already distinguishes the combinations with a normal keymap, and having separate 'a', 'Shift+A' and 'A' (written with caps lock for example) would bring more confusion than benefit. Currently reading the modifier+key combinations is only supported in the output window of those VOs that use x11_common.c event handling. It's not possible to input the key combinations in other VOs or in a terminal window. --- input/input.c | 137 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 48 deletions(-) (limited to 'input/input.c') diff --git a/input/input.c b/input/input.c index 72725a5409..7df91a6922 100644 --- a/input/input.c +++ b/input/input.c @@ -45,6 +45,7 @@ #include "path.h" #include "talloc.h" #include "options.h" +#include "bstr.h" #include "joystick.h" @@ -361,6 +362,16 @@ static const mp_key_name_t key_names[] = { { 0, NULL } }; +struct mp_key_name modifier_names[] = { + { KEY_MODIFIER_SHIFT, "Shift" }, + { KEY_MODIFIER_CTRL, "Ctrl" }, + { KEY_MODIFIER_ALT, "Alt" }, + { KEY_MODIFIER_META, "Meta" }, + { 0 } +}; + +#define KEY_MODIFIER_MASK (KEY_MODIFIER_SHIFT | KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT | KEY_MODIFIER_META) + // This is the default binding. The content of input.conf overrides these. // The first arg is a null terminated array of key codes. // The second is the command @@ -620,8 +631,27 @@ static const m_option_t mp_input_opts[] = { static int default_cmd_func(int fd,char* buf, int l); -static char *get_key_name(int key, char buffer[12]); +static char *get_key_name(int key) +{ + char *ret = talloc_strdup(NULL, ""); + for (int i = 0; modifier_names[i].name; i++) { + if (modifier_names[i].key & key) { + ret = talloc_asprintf_append_buffer(ret, "%s+", + modifier_names[i].name); + key -= modifier_names[i].key; + } + } + for (int i = 0; key_names[i].name != NULL; i++) { + if (key_names[i].key == key) + return talloc_asprintf_append_buffer(ret, "%s", key_names[i].name); + } + + if (isascii(key)) + return talloc_asprintf_append_buffer(ret, "%c", key); + // Print the hex key code + return talloc_asprintf_append_buffer(ret, "%#-8x", key); +} int mp_input_add_cmd_fd(struct input_ctx *ictx, int fd, int select, mp_cmd_func_t read_func, mp_close_func_t close_func) @@ -1034,7 +1064,6 @@ static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys) { char* cmd = NULL; mp_cmd_t* ret; - char key_buf[12]; if (ictx->cmd_binds) cmd = find_bind_for_key(ictx->cmd_binds, n, keys); @@ -1044,12 +1073,16 @@ static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys) cmd = find_bind_for_key(def_cmd_binds,n,keys); if(cmd == NULL) { - mp_tmsg(MSGT_INPUT,MSGL_WARN,"No bind found for key '%s'.", get_key_name(keys[0], - key_buf)); + char *key_buf = get_key_name(keys[0]); + mp_tmsg(MSGT_INPUT,MSGL_WARN,"No bind found for key '%s'.", key_buf); + talloc_free(key_buf); if(n > 1) { int s; - for(s=1; s < n; s++) - mp_msg(MSGT_INPUT,MSGL_WARN,"-%s", get_key_name(keys[s], key_buf)); + for(s=1; s < n; s++) { + key_buf = get_key_name(keys[s]); + mp_msg(MSGT_INPUT,MSGL_WARN,"-%s", key_buf); + talloc_free(key_buf); + } } mp_msg(MSGT_INPUT,MSGL_WARN," \n"); return NULL; @@ -1057,13 +1090,16 @@ static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys) if (strcmp(cmd, "ignore") == 0) return NULL; ret = mp_input_parse_cmd(cmd); if(!ret) { - mp_tmsg(MSGT_INPUT,MSGL_ERR,"Invalid command for bound key %s", - get_key_name(ictx->key_down[0], key_buf)); + char *key_buf = get_key_name(ictx->key_down[0]); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"Invalid command for bound key %s", key_buf); + talloc_free(key_buf); if (ictx->num_key_down > 1) { unsigned int s; - for(s=1; s < ictx->num_key_down; s++) - mp_msg(MSGT_INPUT,MSGL_ERR,"-%s", get_key_name(ictx->key_down[s], - key_buf)); + for(s=1; s < ictx->num_key_down; s++) { + char *key_buf = get_key_name(ictx->key_down[s]); + mp_msg(MSGT_INPUT,MSGL_ERR,"-%s", key_buf); + talloc_free(key_buf); + } } mp_msg(MSGT_INPUT,MSGL_ERR," : %s \n",cmd); } @@ -1076,6 +1112,14 @@ static mp_cmd_t* interpret_key(struct input_ctx *ictx, int code) unsigned int j; mp_cmd_t* ret; + /* On normal keyboards shift changes the character code of non-special + * keys, so don't count the modifier separately for those. In other words + * we want to have "a" and "A" instead of "a" and "Shift+A"; but a separate + * shift modifier is still kept for special keys like arrow keys. + */ + if ((code & ~KEY_MODIFIER_MASK) < 256) + code &= ~KEY_MODIFIER_SHIFT; + if(mp_input_key_cb) { if (code & MP_KEY_DOWN) return NULL; @@ -1371,41 +1415,34 @@ mp_cmd_clone(mp_cmd_t* cmd) { return ret; } -static char *get_key_name(int key, char buffer[12]) +int mp_input_get_key_from_name(const char *name) { - int i; - - for(i = 0; key_names[i].name != NULL; i++) { - if(key_names[i].key == key) - return key_names[i].name; - } - - if(isascii(key)) { - snprintf(buffer, 12, "%c",(char)key); - return buffer; - } - - // Print the hex key code - snprintf(buffer, 12, "%#-8x",key); - return buffer; - -} - -int -mp_input_get_key_from_name(const char *name) { - int i,ret = 0,len = strlen(name); - if(len == 1) { // Direct key code - ret = (unsigned char)name[0]; - return ret; - } else if(len > 2 && strncasecmp("0x",name,2) == 0) - return strtol(name,NULL,16); - - for(i = 0; key_names[i].name != NULL; i++) { - if(strcasecmp(key_names[i].name,name) == 0) - return key_names[i].key; - } + int modifiers = 0; + const char *p; + while (p = strchr(name, '+')) { + for (struct mp_key_name *m = modifier_names; m->name; m++) + if (!bstrcasecmp(BSTR(m->name), (struct bstr){name, p - name})) { + modifiers |= m->key; + goto found; + } + if (!strcmp(name, "+")) + return '+' + modifiers; + return -1; + found: + name = p + 1; + } + int len = strlen(name); + if (len == 1) // Direct key code + return (unsigned char)name[0] + modifiers; + else if (len > 2 && strncasecmp("0x", name, 2) == 0) + return strtol(name, NULL, 16) + modifiers; + + for (int i = 0; key_names[i].name != NULL; i++) { + if (strcasecmp(key_names[i].name, name) == 0) + return key_names[i].key + modifiers; + } - return -1; + return -1; } static int get_input_from_name(char* name,int* keys) { @@ -1595,10 +1632,14 @@ static int parse_config(struct input_ctx *ictx, char *file) // Found new line if(iter[0] == '\n' || iter[0] == '\r') { int i; - char key_buf[12]; - mp_tmsg(MSGT_INPUT,MSGL_ERR,"No command found for key %s", get_key_name(keys[0], key_buf)); - for(i = 1; keys[i] != 0 ; i++) - mp_msg(MSGT_INPUT,MSGL_ERR,"-%s", get_key_name(keys[i], key_buf)); + char *key_buf = get_key_name(keys[0]); + mp_tmsg(MSGT_INPUT,MSGL_ERR,"No command found for key %s", key_buf); + talloc_free(key_buf); + for(i = 1; keys[i] != 0 ; i++) { + char *key_buf = get_key_name(keys[i]); + mp_msg(MSGT_INPUT,MSGL_ERR,"-%s", key_buf); + talloc_free(key_buf); + } mp_msg(MSGT_INPUT,MSGL_ERR,"\n"); keys[0] = 0; if(iter > buffer) { -- cgit v1.2.3 From 5bb2f9787f557bd91d5eb9021238ed7b131d5fa9 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sun, 19 Dec 2010 13:34:06 +0200 Subject: input: add default keybindings Shift+[arrow] for small exact seeks --- input/input.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'input/input.c') diff --git a/input/input.c b/input/input.c index 7df91a6922..faa4cbb073 100644 --- a/input/input.c +++ b/input/input.c @@ -396,8 +396,12 @@ static const mp_cmd_bind_t def_cmd_binds[] = { { { KEY_RIGHT, 0 }, "seek 10" }, { { KEY_LEFT, 0 }, "seek -10" }, + { { KEY_MODIFIER_SHIFT + KEY_RIGHT, 0 }, "seek 1 0 1" }, + { { KEY_MODIFIER_SHIFT + KEY_LEFT, 0 }, "seek -1 0 1" }, { { KEY_UP, 0 }, "seek 60" }, { { KEY_DOWN, 0 }, "seek -60" }, + { { KEY_MODIFIER_SHIFT + KEY_UP, 0 }, "seek 5 0 1" }, + { { KEY_MODIFIER_SHIFT + KEY_DOWN, 0 }, "seek -5 0 1" }, { { KEY_PAGE_UP, 0 }, "seek 600" }, { { KEY_PAGE_DOWN, 0 }, "seek -600" }, { { '+', 0 }, "audio_delay 0.100" }, -- cgit v1.2.3