diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/input/input.c | 138 |
1 files changed, 76 insertions, 62 deletions
diff --git a/core/input/input.c b/core/input/input.c index 038d6507bb..bec4331eec 100644 --- a/core/input/input.c +++ b/core/input/input.c @@ -71,6 +71,7 @@ struct cmd_bind { int input[MP_MAX_KEY_DOWN + 1]; char *cmd; char *location; // filename/line number of definition + bool is_builtin; struct cmd_bind_section *owner; }; @@ -481,7 +482,6 @@ struct input_fd { struct cmd_bind_section { struct cmd_bind *cmd_binds; - bool is_builtin; char *section; struct mp_rect mouse_area; // set at runtime, if at all bool mouse_area_set; // mouse_area is valid and should be tested @@ -1111,7 +1111,7 @@ static void append_bind_info(char **pmsg, struct cmd_bind *bind) msg = talloc_asprintf_append(msg, " in section {%s}", bind->owner->section); msg = talloc_asprintf_append(msg, " in %s", bind->location); - if (bind->owner->is_builtin) + if (bind->is_builtin) msg = talloc_asprintf_append(msg, " (default)"); talloc_free(cmd); *pmsg = msg; @@ -1163,27 +1163,29 @@ static bool bind_matches_key(struct cmd_bind *bind, int n, int *keys) static struct cmd_bind *find_bind_for_key(struct cmd_bind *binds, int n, int *keys) { - int j; - if (n <= 0 || !binds) return NULL; - for (j = 0; binds[j].cmd != NULL; j++) { - if (bind_matches_key(&binds[j], n, keys)) - break; + + // Prefer user-defined keys over builtin bindings + for (int builtin = 0; builtin < 2; builtin++) { + for (int j = 0; binds[j].cmd != NULL; j++) { + if (binds[j].is_builtin == (bool)builtin && + bind_matches_key(&binds[j], n, keys)) + return &binds[j]; + } } - return binds[j].cmd ? &binds[j] : NULL; + return NULL; } static struct cmd_bind_section *get_bind_section(struct input_ctx *ictx, - bool builtin, bstr section) + bstr section) { struct cmd_bind_section *bind_section = ictx->cmd_bind_sections; if (section.len == 0) section = bstr0("default"); while (bind_section) { - if (bstrcmp0(section, bind_section->section) == 0 - && builtin == bind_section->is_builtin) + if (bstrcmp0(section, bind_section->section) == 0) return bind_section; if (bind_section->next == NULL) break; @@ -1198,47 +1200,39 @@ static struct cmd_bind_section *get_bind_section(struct input_ctx *ictx, } *bind_section = (struct cmd_bind_section) { .section = bstrdup0(bind_section, section), - .is_builtin = builtin, }; return bind_section; } +static struct cmd_bind *find_bind_for_key_section(struct input_ctx *ictx, + char *section, + int n, int *keys) +{ + struct cmd_bind_section *bs = get_bind_section(ictx, bstr0(section)); + return find_bind_for_key(bs->cmd_binds, n, keys); +} + static struct cmd_bind *find_any_bind_for_key(struct input_ctx *ictx, char *force_section, int n, int *keys) { - if (force_section) { - for (int b = 0; b < 2; b++) { - bool builtin = !!b; - struct cmd_bind_section *bs = get_bind_section(ictx, builtin, - bstr0(force_section)); - struct cmd_bind *cmd = find_bind_for_key(bs->cmd_binds, n, keys); - if (cmd) - return cmd; - } - return NULL; - } + if (force_section) + return find_bind_for_key_section(ictx, force_section, n, keys); for (int i = ictx->num_active_sections - 1; i >= 0; i--) { - struct active_section *as = &ictx->active_sections[i]; - bstr name = bstr0(as->name); - for (int b = 0; b < 2; b++) { - bool builtin = !!b; - struct cmd_bind_section *bs = get_bind_section(ictx, builtin, name); + struct active_section *s = &ictx->active_sections[i]; + struct cmd_bind *bind = find_bind_for_key_section(ictx, s->name, n, keys); + if (bind) { + struct cmd_bind_section *bs = bind->owner; for (int i = 0; i < n; i++) { - if (MP_KEY_DEPENDS_ON_MOUSE_POS(keys[i]) && - bs->mouse_area_set && - !test_rect(&bs->mouse_area, - ictx->mouse_vo_x, - ictx->mouse_vo_y)) + if (MP_KEY_DEPENDS_ON_MOUSE_POS(keys[i]) && bs->mouse_area_set && + !test_rect(&bs->mouse_area, ictx->mouse_vo_x, ictx->mouse_vo_y)) goto skip; } - struct cmd_bind *cmd = find_bind_for_key(bs->cmd_binds, n, keys); - if (cmd) - return cmd; - skip: ; + return bind; } - if (as->flags & MP_INPUT_EXCLUSIVE) + skip: ; + if (s->flags & MP_INPUT_EXCLUSIVE) break; } @@ -1769,16 +1763,15 @@ static void bind_keys(struct input_ctx *ictx, bool builtin, bstr section, { int i = 0, j; struct cmd_bind *bind = NULL; - struct cmd_bind_section *bind_section = NULL; - - bind_section = get_bind_section(ictx, builtin, section); + struct cmd_bind_section *bind_section = get_bind_section(ictx, section); if (bind_section->cmd_binds) { for (i = 0; bind_section->cmd_binds[i].cmd != NULL; i++) { - for (j = 0; bind_section->cmd_binds[i].input[j] == keys[j] && keys[j] != 0; j++) + struct cmd_bind *b = &bind_section->cmd_binds[i]; + for (j = 0; b->input[j] == keys[j] && keys[j] != 0; j++) /* NOTHING */; - if (keys[j] == 0 && bind_section->cmd_binds[i].input[j] == 0 ) { - bind = &bind_section->cmd_binds[i]; + if (keys[j] == 0 && b->input[j] == 0 && b->is_builtin == builtin) { + bind = b; break; } } @@ -1795,6 +1788,7 @@ static void bind_keys(struct input_ctx *ictx, bool builtin, bstr section, bind->cmd = bstrdup0(bind_section->cmd_binds, command); bind->location = talloc_strdup(bind_section->cmd_binds, loc); bind->owner = bind_section; + bind->is_builtin = builtin; memcpy(bind->input, keys, (MP_MAX_KEY_DOWN + 1) * sizeof(int)); } @@ -1881,10 +1875,17 @@ static int parse_config_file(struct input_ctx *ictx, char *file, bool warn) return 1; } +// If name is NULL, return "default". +// Return a statically allocated name of the section (i.e. return value never +// gets deallocated). +static char *normalize_section(struct input_ctx *ictx, char *name) +{ + return get_bind_section(ictx, bstr0(name))->section; +} + void mp_input_disable_section(struct input_ctx *ictx, char *name) { - struct cmd_bind_section *s = get_bind_section(ictx, false, bstr0(name)); - name = s->section; // get allocated name, reduce NULL to "default" + name = normalize_section(ictx, name); // Remove old section, or make sure it's on top if re-enabled for (int i = ictx->num_active_sections - 1; i >= 0; i--) { @@ -1899,8 +1900,7 @@ void mp_input_disable_section(struct input_ctx *ictx, char *name) void mp_input_enable_section(struct input_ctx *ictx, char *name, int flags) { - struct cmd_bind_section *s = get_bind_section(ictx, false, bstr0(name)); - name = s->section; // get allocated name, reduce NULL to "default" + name = normalize_section(ictx, name); mp_input_disable_section(ictx, name); @@ -1918,22 +1918,18 @@ void mp_input_disable_all_sections(struct input_ctx *ictx) void mp_input_set_section_mouse_area(struct input_ctx *ictx, char *name, int x0, int y0, int x1, int y1) { - for (int b = 0; b < 2; b++) { - struct cmd_bind_section *s = get_bind_section(ictx, !!b, bstr0(name)); - s->mouse_area = (struct mp_rect){x0, y0, x1, y1}; - s->mouse_area_set = x0 != x1 && y0 != y1; - } + struct cmd_bind_section *s = get_bind_section(ictx, bstr0(name)); + s->mouse_area = (struct mp_rect){x0, y0, x1, y1}; + s->mouse_area_set = x0 != x1 && y0 != y1; } bool mp_input_test_mouse_active(struct input_ctx *ictx, int x, int y) { for (int i = 0; i < ictx->num_active_sections; i++) { char *name = ictx->active_sections[i].name; - for (int b = 0; b < 2; b++) { - struct cmd_bind_section *s = get_bind_section(ictx, !!b, bstr0(name)); - if (s->mouse_area_set && test_rect(&s->mouse_area, x, y)) - return true; - } + struct cmd_bind_section *s = get_bind_section(ictx, bstr0(name)); + if (s->mouse_area_set && test_rect(&s->mouse_area, x, y)) + return true; } return false; } @@ -1943,6 +1939,26 @@ bool mp_input_test_dragging(struct input_ctx *ictx, int x, int y) return mp_input_test_mouse_active(ictx, x, y); } +static void remove_binds(struct cmd_bind *binds, bool builtin) +{ + if (!binds) + return; + int count; + for (int n = 0; binds[n].cmd; n++) + count++; + int n = 0; + while (binds[n].cmd) { + if (binds[n].is_builtin == builtin) { + talloc_free(binds[n].cmd); + talloc_free(binds[n].location); + // Remove by swapping in the last item (or the terminator) + binds[n] = binds[count - 1]; + } else { + n++; + } + } +} + void mp_input_define_section(struct input_ctx *ictx, char *name, char *location, char *contents, bool builtin) { @@ -1954,10 +1970,8 @@ void mp_input_define_section(struct input_ctx *ictx, char *name, char *location, // Disable: mp_input_disable_section(ictx, name); // Delete: - struct cmd_bind_section *s = get_bind_section(ictx, builtin, bstr0(name)); - talloc_free(s->cmd_binds); - s->cmd_binds = NULL; - // Could remove the section itself too, but that's not really necessary. + struct cmd_bind_section *s = get_bind_section(ictx, bstr0(name)); + remove_binds(s->cmd_binds, builtin); } } |