st/oxr: store preferred path per binding, not per action

Fixes d62c2d2011

For any one action, multiple bindings may be suggested. The preferred/matched
input path depends on which binding is active.

Each bindings already stores a list of actions for which the suggested bindings
matched any of the input paths, just add a corresponding list *which* path matched.
This commit is contained in:
Christoph Haag 2020-05-04 17:22:15 +02:00
parent 2a58d1225f
commit cf0e5d7861
3 changed files with 33 additions and 19 deletions

View file

@ -179,7 +179,9 @@ static void
reset_binding_keys(struct oxr_binding *binding)
{
free(binding->keys);
free(binding->preferred_binding_path_index);
binding->keys = NULL;
binding->preferred_binding_path_index = NULL;
binding->num_keys = 0;
}
@ -195,17 +197,17 @@ static void
add_key_to_matching_bindings(struct oxr_binding *bindings,
size_t num_bindings,
XrPath path,
uint32_t key,
uint32_t *preferred_binding_path)
uint32_t key)
{
for (size_t x = 0; x < num_bindings; x++) {
struct oxr_binding *b = &bindings[x];
bool found = false;
uint32_t preferred_path_index;
for (size_t y = 0; y < b->num_paths; y++) {
if (b->paths[y] == path) {
found = true;
*preferred_binding_path = y;
preferred_path_index = y;
break;
}
}
@ -215,6 +217,10 @@ add_key_to_matching_bindings(struct oxr_binding *bindings,
}
U_ARRAY_REALLOC_OR_FREE(b->keys, uint32_t, (b->num_keys + 1));
U_ARRAY_REALLOC_OR_FREE(b->preferred_binding_path_index,
uint32_t, (b->num_keys + 1));
b->preferred_binding_path_index[b->num_keys] =
preferred_path_index;
b->keys[b->num_keys++] = key;
}
}
@ -393,9 +399,8 @@ oxr_action_suggest_interaction_profile_bindings(
fprintf(stderr, "\t\t%s %i -> %s\n", act->name, act->key, str);
#endif
add_key_to_matching_bindings(
bindings, num_bindings, s->binding, act->key,
&act->preferred_binding_path_index);
add_key_to_matching_bindings(bindings, num_bindings, s->binding,
act->key);
}
return XR_SUCCESS;

View file

@ -375,6 +375,22 @@ oxr_source_cache_determine_redirect(struct oxr_logger *log,
}
}
static XrPath
get_matched_xrpath(struct oxr_binding *b, struct oxr_action *act)
{
XrPath preferred_path = XR_NULL_PATH;
for (uint32_t i = 0; i < b->num_keys; i++) {
if (b->keys[i] == act->key) {
uint32_t preferred_path_index = XR_NULL_PATH;
preferred_path_index =
b->preferred_binding_path_index[i];
preferred_path = b->paths[preferred_path_index];
break;
}
}
return preferred_path;
}
static void
get_binding(struct oxr_logger *log,
struct oxr_sink_logger *slog,
@ -449,15 +465,9 @@ get_binding(struct oxr_logger *log,
const char *str = NULL;
struct oxr_binding *b = bindings[i];
// pick the path that the action prefers.
// e.g. an action bound to /user/hand/*/trackpad will prefer
// index 0 of those bindings, an action bound to
// /user/hand/*/trackpad will prefer index 1
// [/user/hand/*/trackpad, /user/hand/*/trackpad/x]
XrPath matched_path = get_matched_xrpath(b, act);
XrPath preferred_path =
b->paths[act->preferred_binding_path_index];
oxr_path_get_string(log, sess->sys->inst, preferred_path, &str,
oxr_path_get_string(log, sess->sys->inst, matched_path, &str,
&length);
oxr_slog(slog, "\t\t\tBinding: %s\n", str);
@ -470,7 +480,7 @@ get_binding(struct oxr_logger *log,
outputs, num_outputs);
if (found) {
*bound_path = preferred_path;
*bound_path = matched_path;
oxr_slog(slog, "\t\t\t\tBound!\n");
} else {
oxr_slog(slog, "\t\t\t\tRejected! (NO XDEV MAPPING)\n");

View file

@ -1081,8 +1081,10 @@ struct oxr_binding
enum oxr_sub_action_path sub_path;
uint32_t *keys;
size_t num_keys;
uint32_t *keys;
//! store which entry in paths was suggested, for each action key
uint32_t *preferred_binding_path_index;
enum xrt_input_name *inputs;
size_t num_inputs;
@ -1337,9 +1339,6 @@ struct oxr_action
//! Which sub action paths that this action was created with.
struct oxr_sub_paths sub_paths;
//! Which of the paths in oxr_binding.paths matches this action.
uint32_t preferred_binding_path_index;
};
/*!