The open source OpenXR runtime

st/oxr: Improve input binding to better support asymetrical controller buttons

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2632>

authored by

Jakob Bornecrantz and committed by
Marge Bot
00e84197 5bde33f8

+70 -27
+70 -27
src/xrt/state_trackers/oxr/oxr_input.c
··· 514 514 */ 515 515 516 516 static bool 517 + find_xdev_name_from_pairs(const struct xrt_device *xdev, 518 + const struct xrt_binding_profile *xbp, 519 + enum xrt_input_name from_name, 520 + enum xrt_input_name *out_name) 521 + { 522 + if (from_name == 0) { 523 + *out_name = 0; 524 + return true; // Not asking for anything, just keep going. 525 + } 526 + 527 + /* 528 + * For asymmetrical devices like PS Sense being re-bound to a symmetrical 529 + * "device" like simple controller can be problemantic as depending on 530 + * which hand it is menu is bound to different inputs. Instead of making 531 + * the driver have two completely unique binding mappings per hand, we 532 + * instead loop over all pairs finding the first match. In other words 533 + * this means there can be multiple of the same 'from' value in the 534 + * array of input pairs. 535 + */ 536 + for (size_t i = 0; i < xbp->input_count; i++) { 537 + if (from_name != xbp->inputs[i].from) { 538 + continue; 539 + } 540 + 541 + // What is the name on the xdev? 542 + enum xrt_input_name xdev_name = xbp->inputs[i].device; 543 + 544 + // See if we can't find it. 545 + for (uint32_t k = 0; k < xdev->input_count; k++) { 546 + if (xdev->inputs[k].name == xdev_name) { 547 + *out_name = xdev_name; 548 + return true; 549 + } 550 + } 551 + } 552 + 553 + return false; 554 + } 555 + 556 + static bool 517 557 do_inputs(struct oxr_binding *binding_point, 518 558 struct xrt_device *xdev, 519 559 struct xrt_binding_profile *xbp, ··· 522 562 uint32_t *input_count) 523 563 { 524 564 enum xrt_input_name name = 0; 525 - if (xbp == NULL) { 526 - name = binding_point->input; 527 - } else { 528 - for (size_t i = 0; i < xbp->input_count; i++) { 529 - if (binding_point->input != xbp->inputs[i].from) { 530 - continue; 531 - } 565 + enum xrt_input_name dpad_activate_name = 0; 532 566 533 - // We have found a device mapping. 534 - name = xbp->inputs[i].device; 535 - break; 536 - } 567 + if (xbp != NULL) { 568 + bool t1 = find_xdev_name_from_pairs(xdev, xbp, binding_point->input, &name); 569 + bool t2 = find_xdev_name_from_pairs(xdev, xbp, binding_point->dpad_activate, &dpad_activate_name); 537 570 538 - // Didn't find a mapping. 539 - if (name == 0) { 571 + // We couldn't find the needed inputs on the device. 572 + if (!t1 || !t2) { 540 573 return false; 541 574 } 575 + } else { 576 + name = binding_point->input; 577 + dpad_activate_name = binding_point->dpad_activate; 542 578 } 543 579 544 580 struct xrt_input *input = NULL; 545 - if (oxr_xdev_find_input(xdev, name, &input)) { 546 - uint32_t index = (*input_count)++; 547 - inputs[index].input = input; 548 - inputs[index].xdev = xdev; 549 - inputs[index].bound_path = matched_path; 550 - if (binding_point->dpad_activate != 0) { 551 - struct xrt_input *dpad_activate = NULL; 552 - if (!oxr_xdev_find_input(xdev, binding_point->dpad_activate, &dpad_activate)) { 553 - return false; 554 - } 555 - inputs[index].dpad_activate_name = binding_point->dpad_activate; 556 - inputs[index].dpad_activate = dpad_activate; 581 + struct xrt_input *dpad_activate_input = NULL; 582 + 583 + // Early out if there is no such input. 584 + if (!oxr_xdev_find_input(xdev, name, &input)) { 585 + return false; 586 + } 587 + 588 + // Check this before allocating an input. 589 + if (dpad_activate_name != 0) { 590 + if (!oxr_xdev_find_input(xdev, dpad_activate_name, &dpad_activate_input)) { 591 + return false; 557 592 } 558 - return true; 559 593 } 560 594 561 - return false; 595 + uint32_t index = (*input_count)++; 596 + inputs[index].input = input; 597 + inputs[index].xdev = xdev; 598 + inputs[index].bound_path = matched_path; 599 + if (dpad_activate_input != NULL) { 600 + inputs[index].dpad_activate_name = dpad_activate_name; 601 + inputs[index].dpad_activate = dpad_activate_input; 602 + } 603 + 604 + return true; 562 605 } 563 606 564 607 static bool