summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-22 23:26:44 +0200
committerwm4 <wm4@nowhere>2013-06-29 22:58:14 +0200
commit12ac3356bf82aa84f8caefecea9dd24be0e66ebb (patch)
treef362ebde9273cb69a427d7f19fe9a9218cf99eef
parent1099e0fc998763cb9c16027710720ce198a91258 (diff)
downloadmpv-12ac3356bf82aa84f8caefecea9dd24be0e66ebb.tar.bz2
mpv-12ac3356bf82aa84f8caefecea9dd24be0e66ebb.tar.xz
input: don't keep separate sections for builtin key bindings
Instead mark individual key bindings as builtin. Not sure whether this is conceptually simpler or more complicated. For one, it requires the annoying remove_binds() function to wipe existing bindings instead of just killing the section, on the other hand it gets rid of almost all special handling of builtin vs. normal sections.
-rw-r--r--core/input/input.c138
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);
}
}