mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-02-15 10:10:07 +00:00
d/wmr: Do device creation via builder interface
This commit is contained in:
parent
56dd75c14d
commit
2ddf868735
src/xrt
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include "xrt/xrt_prober.h"
|
||||
|
||||
#include "wmr_common.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -33,6 +35,121 @@ extern "C" {
|
|||
*/
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Builder interface.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Results from searching for host attached Bluetooth controllers.
|
||||
*
|
||||
* @ingroup drv_wmr
|
||||
*/
|
||||
struct wmr_bt_controllers_search_results
|
||||
{
|
||||
struct xrt_prober_device *left;
|
||||
struct xrt_prober_device *right;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Search for a left and right pair of Windows Mixed Reality controllers, groups
|
||||
* them by type (Classic/Odyssey/G2). Preferring Odyssey over Classic. Will mix
|
||||
* types in order to get a complete left and right pair if need be, but prefers
|
||||
* matching types first. G2 currently not supported.
|
||||
*
|
||||
* @ingroup drv_wmr
|
||||
*/
|
||||
void
|
||||
wmr_find_bt_controller_pair(struct xrt_prober *xp,
|
||||
struct xrt_prober_device **xpdevs,
|
||||
size_t xpdev_count,
|
||||
enum u_logging_level log_level,
|
||||
struct wmr_bt_controllers_search_results *out_wbtcsr);
|
||||
|
||||
/*!
|
||||
* Results from searching for a companion device. Doctor?
|
||||
*
|
||||
* @ingroup drv_wmr
|
||||
*/
|
||||
struct wmr_companion_search_results
|
||||
{
|
||||
struct xrt_prober_device *xpdev_companion;
|
||||
enum wmr_headset_type type;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Searches for the the list of xpdevs for the companion device of a holo lens
|
||||
* device.
|
||||
*
|
||||
* @ingroup drv_wmr
|
||||
*/
|
||||
void
|
||||
wmr_find_companion_device(struct xrt_prober *xp,
|
||||
struct xrt_prober_device **xpdevs,
|
||||
size_t xpdev_count,
|
||||
enum u_logging_level log_level,
|
||||
struct xrt_prober_device *xpdev_holo,
|
||||
struct wmr_companion_search_results *out_wcsr);
|
||||
|
||||
/*!
|
||||
* Results from searching for a headset.
|
||||
*
|
||||
* @ingroup drv_wmr
|
||||
*/
|
||||
struct wmr_headset_search_results
|
||||
{
|
||||
struct xrt_prober_device *xpdev_holo;
|
||||
struct xrt_prober_device *xpdev_companion;
|
||||
enum wmr_headset_type type;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Find a headsets.
|
||||
*
|
||||
* @ingroup drv_wmr
|
||||
*/
|
||||
void
|
||||
wmr_find_headset(struct xrt_prober *xp,
|
||||
struct xrt_prober_device **xpdevs,
|
||||
size_t xpdev_count,
|
||||
enum u_logging_level log_level,
|
||||
struct wmr_headset_search_results *out_whsr);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Creation extensions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Creates a WMR headset with the given devices and of headset type.
|
||||
*
|
||||
* @ingroup drv_wmr
|
||||
*/
|
||||
xrt_result_t
|
||||
wmr_create_headset(struct xrt_prober *xp,
|
||||
struct xrt_prober_device *xpdev_holo,
|
||||
struct xrt_prober_device *xpdev_companion,
|
||||
enum wmr_headset_type type,
|
||||
enum u_logging_level log_level,
|
||||
struct xrt_device **out_hmd,
|
||||
struct xrt_device **out_left,
|
||||
struct xrt_device **out_right);
|
||||
|
||||
/*!
|
||||
* Creates a WMR BT controller device.
|
||||
*
|
||||
* @ingroup drv_wmr
|
||||
*/
|
||||
xrt_result_t
|
||||
wmr_create_bt_controller(struct xrt_prober *xp,
|
||||
struct xrt_prober_device *xpdev,
|
||||
enum u_logging_level log_level,
|
||||
struct xrt_device **out_xdev);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Found functions.
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "xrt/xrt_config_drivers.h"
|
||||
#include "xrt/xrt_prober.h"
|
||||
|
||||
#include "os/os_hid.h"
|
||||
|
||||
#include "util/u_misc.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_prober.h"
|
||||
|
@ -48,6 +50,37 @@ DEBUG_GET_ONCE_LOG_OPTION(wmr_log, "WMR_LOG", U_LOGGING_INFO)
|
|||
*
|
||||
*/
|
||||
|
||||
static bool
|
||||
is_left(const char *product_name, size_t size)
|
||||
{
|
||||
return strncmp(product_name, WMR_CONTROLLER_LEFT_PRODUCT_STRING, size) == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_right(const char *product_name, size_t size)
|
||||
{
|
||||
return strncmp(product_name, WMR_CONTROLLER_RIGHT_PRODUCT_STRING, size) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
classify_and_assign_controller(struct xrt_prober *xp,
|
||||
struct xrt_prober_device *xpd,
|
||||
struct wmr_bt_controllers_search_results *ctrls)
|
||||
{
|
||||
char buf[256] = {0};
|
||||
int result = xrt_prober_get_string_descriptor(xp, xpd, XRT_PROBER_STRING_PRODUCT, (uint8_t *)buf, sizeof(buf));
|
||||
if (result <= 0) {
|
||||
U_LOG_E("xrt_prober_get_string_descriptor: %i\n\tFailed to get product string!", result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_left(buf, sizeof(buf))) {
|
||||
ctrls->left = xpd;
|
||||
} else if (is_right(buf, sizeof(buf))) {
|
||||
ctrls->right = xpd;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
check_and_get_interface(struct xrt_prober_device *device,
|
||||
enum u_logging_level log_level,
|
||||
|
@ -144,6 +177,266 @@ find_companion_device(struct xrt_prober *xp,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 'Exported' builder functions.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
wmr_find_bt_controller_pair(struct xrt_prober *xp,
|
||||
struct xrt_prober_device **devices,
|
||||
size_t device_count,
|
||||
enum u_logging_level log_level,
|
||||
struct wmr_bt_controllers_search_results *out_wbtcsr)
|
||||
{
|
||||
// Try to pair controllers of the same type.
|
||||
struct wmr_bt_controllers_search_results odyssey_ctrls = {0};
|
||||
struct wmr_bt_controllers_search_results wmr_ctrls = {0};
|
||||
|
||||
for (size_t i = 0; i < device_count; i++) {
|
||||
struct xrt_prober_device *xpd = devices[i];
|
||||
|
||||
// All controllers have the Microsoft vendor ID.
|
||||
if (xpd->vendor_id != MICROSOFT_VID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only handle Bluetooth connected controllers here.
|
||||
if (xpd->bus != XRT_BUS_TYPE_BLUETOOTH) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpd->product_id == WMR_CONTROLLER_PID) {
|
||||
classify_and_assign_controller(xp, xpd, &wmr_ctrls);
|
||||
} else if (xpd->product_id == ODYSSEY_CONTROLLER_PID) {
|
||||
classify_and_assign_controller(xp, xpd, &odyssey_ctrls);
|
||||
} else if (xpd->product_id == REVERB_G2_CONTROLLER_PID) {
|
||||
U_LOG_W(
|
||||
"Reverb G2 controller connected to host BT controller, correnntly not supported, "
|
||||
"skipping!");
|
||||
}
|
||||
}
|
||||
|
||||
// We have to prefer one type pair, prefer Odyssey.
|
||||
if (odyssey_ctrls.left != NULL && odyssey_ctrls.right != NULL) {
|
||||
*out_wbtcsr = odyssey_ctrls;
|
||||
return;
|
||||
}
|
||||
|
||||
// Other type pair.
|
||||
if (wmr_ctrls.left != NULL && wmr_ctrls.right != NULL) {
|
||||
*out_wbtcsr = wmr_ctrls;
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab any of them.
|
||||
out_wbtcsr->left = odyssey_ctrls.left != NULL ? odyssey_ctrls.left : wmr_ctrls.left;
|
||||
out_wbtcsr->right = odyssey_ctrls.right != NULL ? odyssey_ctrls.right : wmr_ctrls.right;
|
||||
}
|
||||
|
||||
void
|
||||
wmr_find_companion_device(struct xrt_prober *xp,
|
||||
struct xrt_prober_device **xpdevs,
|
||||
size_t xpdev_count,
|
||||
enum u_logging_level log_level,
|
||||
struct xrt_prober_device *xpdev_holo,
|
||||
struct wmr_companion_search_results *out_wcsr)
|
||||
{
|
||||
struct xrt_prober_device *xpdev_companion = NULL;
|
||||
enum wmr_headset_type type = WMR_HEADSET_GENERIC;
|
||||
|
||||
if (!find_companion_device(xp, xpdevs, xpdev_count, log_level, &type, &xpdev_companion)) {
|
||||
U_LOG_IFL_E(log_level, "Did not find HoloLens Sensors' companion device");
|
||||
return;
|
||||
}
|
||||
|
||||
out_wcsr->xpdev_companion = xpdev_companion;
|
||||
out_wcsr->type = type;
|
||||
}
|
||||
|
||||
void
|
||||
wmr_find_headset(struct xrt_prober *xp,
|
||||
struct xrt_prober_device **xpdevs,
|
||||
size_t xpdev_count,
|
||||
enum u_logging_level log_level,
|
||||
struct wmr_headset_search_results *out_whsr)
|
||||
{
|
||||
struct wmr_companion_search_results wcsr = {0};
|
||||
struct xrt_prober_device *xpdev_holo = NULL;
|
||||
|
||||
for (size_t i = 0; i < xpdev_count; i++) {
|
||||
struct xrt_prober_device *xpd = xpdevs[i];
|
||||
|
||||
// Only handle Bluetooth connected controllers here.
|
||||
if (xpd->bus != XRT_BUS_TYPE_USB) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpd->vendor_id != MICROSOFT_VID || xpd->product_id != HOLOLENS_SENSORS_PID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
xpdev_holo = xpd;
|
||||
break;
|
||||
}
|
||||
|
||||
// Did we find any?
|
||||
if (xpdev_holo == NULL) {
|
||||
U_LOG_IFL_D(log_level, "Did not find HoloLens Sensors device, no headset connected?");
|
||||
return; // Didn't find any hololense device, not an error.
|
||||
}
|
||||
|
||||
|
||||
// Find the companion device.
|
||||
wmr_find_companion_device(xp, xpdevs, xpdev_count, log_level, xpdev_holo, &wcsr);
|
||||
if (wcsr.xpdev_companion == NULL) {
|
||||
U_LOG_IFL_E(log_level, "Found a HoloLens device, but not it's companion device");
|
||||
return;
|
||||
}
|
||||
|
||||
// Done now, output.
|
||||
out_whsr->xpdev_holo = xpdev_holo;
|
||||
out_whsr->xpdev_companion = wcsr.xpdev_companion;
|
||||
out_whsr->type = wcsr.type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 'Exported' create functions.
|
||||
*
|
||||
*/
|
||||
|
||||
xrt_result_t
|
||||
wmr_create_headset(struct xrt_prober *xp,
|
||||
struct xrt_prober_device *xpdev_holo,
|
||||
struct xrt_prober_device *xpdev_companion,
|
||||
enum wmr_headset_type type,
|
||||
enum u_logging_level log_level,
|
||||
struct xrt_device **out_hmd,
|
||||
struct xrt_device **out_left,
|
||||
struct xrt_device **out_right)
|
||||
{
|
||||
DRV_TRACE_MARKER();
|
||||
|
||||
U_LOG_IFL_D(log_level, "Creating headset.");
|
||||
|
||||
const int interface_holo = 2;
|
||||
const int interface_companion = 0;
|
||||
int ret;
|
||||
|
||||
struct os_hid_device *hid_holo = NULL;
|
||||
ret = xrt_prober_open_hid_interface(xp, xpdev_holo, interface_holo, &hid_holo);
|
||||
if (ret != 0) {
|
||||
U_LOG_IFL_E(log_level, "Failed to open HoloLens Sensors HID interface");
|
||||
return XRT_ERROR_DEVICE_CREATION_FAILED;
|
||||
}
|
||||
|
||||
struct os_hid_device *hid_companion = NULL;
|
||||
ret = xrt_prober_open_hid_interface(xp, xpdev_companion, interface_companion, &hid_companion);
|
||||
if (ret != 0) {
|
||||
U_LOG_IFL_E(log_level, "Failed to open HoloLens Sensors' companion HID interface.");
|
||||
goto error_holo;
|
||||
}
|
||||
|
||||
struct xrt_device *hmd = NULL;
|
||||
struct xrt_device *ht = NULL;
|
||||
struct xrt_device *two_hands[2] = {NULL, NULL}; // Must initialize, always returned.
|
||||
wmr_hmd_create(type, hid_holo, hid_companion, xpdev_holo, log_level, &hmd, &ht);
|
||||
|
||||
if (hmd == NULL) {
|
||||
U_LOG_IFL_E(log_level, "Failed to create WMR HMD device.");
|
||||
goto error_companion;
|
||||
}
|
||||
|
||||
#ifdef XRT_BUILD_DRIVER_HANDTRACKING
|
||||
if (ht != NULL) { // Create hand-tracked controllers
|
||||
cemu_devices_create(hmd, ht, two_hands);
|
||||
}
|
||||
#endif
|
||||
|
||||
*out_hmd = hmd;
|
||||
*out_left = two_hands[0];
|
||||
*out_right = two_hands[1];
|
||||
|
||||
return XRT_SUCCESS;
|
||||
|
||||
error_companion:
|
||||
os_hid_destroy(hid_companion);
|
||||
error_holo:
|
||||
os_hid_destroy(hid_holo);
|
||||
|
||||
return XRT_ERROR_DEVICE_CREATION_FAILED;
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
wmr_create_bt_controller(struct xrt_prober *xp,
|
||||
struct xrt_prober_device *xpdev,
|
||||
enum u_logging_level log_level,
|
||||
struct xrt_device **out_xdev)
|
||||
{
|
||||
DRV_TRACE_MARKER();
|
||||
|
||||
U_LOG_IFL_D(log_level, "Creating Bluetooth controller.");
|
||||
|
||||
struct os_hid_device *hid_controller = NULL;
|
||||
|
||||
// Only handle Bluetooth connected controllers here.
|
||||
if (xpdev->bus != XRT_BUS_TYPE_BLUETOOTH) {
|
||||
U_LOG_IFL_E(log_level, "Got a non Bluetooth device!");
|
||||
return XRT_ERROR_DEVICE_CREATION_FAILED;
|
||||
}
|
||||
|
||||
char product_name[XRT_DEVICE_PRODUCT_NAME_LEN] = {0};
|
||||
int ret = xrt_prober_get_string_descriptor( //
|
||||
xp, //
|
||||
xpdev, //
|
||||
XRT_PROBER_STRING_PRODUCT, //
|
||||
(uint8_t *)product_name, //
|
||||
sizeof(product_name)); //
|
||||
|
||||
enum xrt_device_type controller_type = XRT_DEVICE_TYPE_UNKNOWN;
|
||||
const int interface_controller = 0;
|
||||
|
||||
switch (xpdev->product_id) {
|
||||
case WMR_CONTROLLER_PID:
|
||||
case ODYSSEY_CONTROLLER_PID:
|
||||
case REVERB_G2_CONTROLLER_PID:
|
||||
if (is_left(product_name, sizeof(product_name))) {
|
||||
controller_type = XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER;
|
||||
break;
|
||||
} else if (is_right(product_name, sizeof(product_name))) {
|
||||
controller_type = XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER;
|
||||
break;
|
||||
}
|
||||
// else fall through
|
||||
default:
|
||||
U_LOG_IFL_E(log_level,
|
||||
"Unsupported controller device (Bluetooth): vid: 0x%04X, pid: 0x%04X, Product Name: '%s'",
|
||||
xpdev->vendor_id, xpdev->product_id, product_name);
|
||||
return XRT_ERROR_DEVICE_CREATION_FAILED;
|
||||
}
|
||||
|
||||
ret = xrt_prober_open_hid_interface(xp, xpdev, interface_controller, &hid_controller);
|
||||
if (ret != 0) {
|
||||
U_LOG_IFL_E(log_level, "Failed to open WMR Bluetooth controller's HID interface");
|
||||
return XRT_ERROR_DEVICE_CREATION_FAILED;
|
||||
}
|
||||
|
||||
struct xrt_device *xdev = wmr_bt_controller_create(hid_controller, controller_type, log_level);
|
||||
if (xdev == NULL) {
|
||||
U_LOG_IFL_E(log_level, "Failed to create WMR controller (Bluetooth)");
|
||||
os_hid_destroy(hid_controller);
|
||||
return XRT_ERROR_DEVICE_CREATION_FAILED;
|
||||
}
|
||||
|
||||
*out_xdev = xdev;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 'Exported' found functions.
|
||||
|
|
|
@ -11,13 +11,17 @@
|
|||
#include "xrt/xrt_prober.h"
|
||||
|
||||
#include "util/u_misc.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_logging.h"
|
||||
#include "util/u_builders.h"
|
||||
#include "util/u_config_json.h"
|
||||
#include "util/u_pretty_print.h"
|
||||
#include "util/u_space_overseer.h"
|
||||
#include "util/u_system_helpers.h"
|
||||
|
||||
#include "target_builder_interface.h"
|
||||
|
||||
#include "wmr/wmr_common.h"
|
||||
#include "wmr/wmr_interface.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -26,6 +30,8 @@
|
|||
#error "Must only be built with XRT_BUILD_DRIVER_WMR set"
|
||||
#endif
|
||||
|
||||
DEBUG_GET_ONCE_LOG_OPTION(wmr_log, "WMR_LOG", U_LOGGING_INFO)
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -37,6 +43,52 @@ static const char *driver_list[] = {
|
|||
"wmr",
|
||||
};
|
||||
|
||||
static void
|
||||
print_hmd(u_pp_delegate_t dg,
|
||||
const char *prefix,
|
||||
enum wmr_headset_type type,
|
||||
struct xrt_prober_device *xpdev_holo,
|
||||
struct xrt_prober_device *xpdev_companion)
|
||||
{
|
||||
u_pp(dg, "\n\t%s: ", prefix);
|
||||
|
||||
if (xpdev_holo == NULL || xpdev_companion == NULL) {
|
||||
u_pp(dg, "None");
|
||||
return;
|
||||
}
|
||||
|
||||
struct xrt_prober_device *c = xpdev_companion;
|
||||
|
||||
switch (type) {
|
||||
case WMR_HEADSET_GENERIC: u_pp(dg, "Generic"); break;
|
||||
case WMR_HEADSET_HP_VR1000: u_pp(dg, "HP VR1000"); break;
|
||||
case WMR_HEADSET_REVERB_G1: u_pp(dg, "Reverb G1"); break;
|
||||
case WMR_HEADSET_REVERB_G2: u_pp(dg, "Reverb G2"); break;
|
||||
case WMR_HEADSET_SAMSUNG_XE700X3AI: u_pp(dg, "Samsung XE700X3AI"); break;
|
||||
case WMR_HEADSET_SAMSUNG_800ZAA: u_pp(dg, "Samsung 800ZAA"); break;
|
||||
case WMR_HEADSET_LENOVO_EXPLORER: u_pp(dg, "Lenovo Explorer"); break;
|
||||
case WMR_HEADSET_MEDION_ERAZER_X1000: u_pp(dg, "Medion Erazer X1000"); break;
|
||||
default: u_pp(dg, "Unknown (VID: %04x, PID: 0x%04x)", c->vendor_id, c->product_id); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_ctrl(u_pp_delegate_t dg, const char *prefix, struct xrt_prober_device *xpdev)
|
||||
{
|
||||
u_pp(dg, "\n\t%s: ", prefix);
|
||||
|
||||
if (xpdev == NULL) {
|
||||
u_pp(dg, "None");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (xpdev->product_id) {
|
||||
case WMR_CONTROLLER_PID: u_pp(dg, "WinMR Controller"); break;
|
||||
case ODYSSEY_CONTROLLER_PID: u_pp(dg, "Odyssey Controller"); break;
|
||||
default: u_pp(dg, "Unknown (VID: %04x, PID: 0x%04x)", xpdev->vendor_id, xpdev->product_id); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -50,6 +102,76 @@ wmr_estimate_system(struct xrt_builder *xb,
|
|||
struct xrt_prober *xp,
|
||||
struct xrt_builder_estimate *out_estimate)
|
||||
{
|
||||
enum u_logging_level log_level = debug_get_log_option_wmr_log();
|
||||
struct wmr_bt_controllers_search_results ctrls = {0};
|
||||
struct wmr_headset_search_results whsr = {0};
|
||||
struct xrt_builder_estimate estimate = {0};
|
||||
struct xrt_prober_device **xpdevs = NULL;
|
||||
size_t xpdev_count = 0;
|
||||
xrt_result_t xret = XRT_SUCCESS;
|
||||
|
||||
/*
|
||||
* Pre device looking stuff.
|
||||
*/
|
||||
|
||||
// Lock the device list
|
||||
xret = xrt_prober_lock_list(xp, &xpdevs, &xpdev_count);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
return xret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Search for devices.
|
||||
*/
|
||||
|
||||
wmr_find_headset(xp, xpdevs, xpdev_count, log_level, &whsr);
|
||||
|
||||
wmr_find_bt_controller_pair(xp, xpdevs, xpdev_count, log_level, &ctrls);
|
||||
|
||||
if (log_level >= U_LOGGING_DEBUG) {
|
||||
struct u_pp_sink_stack_only sink;
|
||||
u_pp_delegate_t dg = u_pp_sink_stack_only_init(&sink);
|
||||
u_pp(dg, "Found:");
|
||||
print_hmd(dg, "head", whsr.type, whsr.xpdev_holo, whsr.xpdev_companion);
|
||||
print_ctrl(dg, "left", ctrls.left);
|
||||
print_ctrl(dg, "right", ctrls.right);
|
||||
|
||||
U_LOG_IFL_D(log_level, "%s", sink.buffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tidy.
|
||||
*/
|
||||
|
||||
xret = xrt_prober_unlock_list(xp, &xpdevs);
|
||||
assert(xret == XRT_SUCCESS);
|
||||
|
||||
|
||||
/*
|
||||
* Fill out estimate.
|
||||
*/
|
||||
|
||||
if (whsr.xpdev_holo != NULL && whsr.xpdev_companion != NULL) {
|
||||
estimate.certain.head = true;
|
||||
|
||||
if (whsr.type == WMR_HEADSET_REVERB_G2) {
|
||||
estimate.maybe.left = true;
|
||||
estimate.maybe.right = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctrls.left != NULL) {
|
||||
estimate.certain.left = true;
|
||||
}
|
||||
|
||||
if (ctrls.right != NULL) {
|
||||
estimate.certain.right = true;
|
||||
}
|
||||
|
||||
*out_estimate = estimate;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -60,7 +182,133 @@ wmr_open_system(struct xrt_builder *xb,
|
|||
struct xrt_system_devices **out_xsysd,
|
||||
struct xrt_space_overseer **out_xso)
|
||||
{
|
||||
enum u_logging_level log_level = debug_get_log_option_wmr_log();
|
||||
struct wmr_bt_controllers_search_results ctrls = {0};
|
||||
struct wmr_headset_search_results whsr = {0};
|
||||
struct xrt_prober_device **xpdevs = NULL;
|
||||
size_t xpdev_count = 0;
|
||||
xrt_result_t xret_unlock = XRT_SUCCESS;
|
||||
xrt_result_t xret = XRT_SUCCESS;
|
||||
|
||||
/*
|
||||
* Pre device looking stuff.
|
||||
*/
|
||||
|
||||
// Lock the device list
|
||||
xret = xrt_prober_lock_list(xp, &xpdevs, &xpdev_count);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
return xret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Search for devices.
|
||||
*/
|
||||
|
||||
wmr_find_headset(xp, xpdevs, xpdev_count, log_level, &whsr);
|
||||
|
||||
wmr_find_bt_controller_pair(xp, xpdevs, xpdev_count, log_level, &ctrls);
|
||||
|
||||
|
||||
/*
|
||||
* Validation.
|
||||
*/
|
||||
|
||||
if (whsr.xpdev_holo == NULL || whsr.xpdev_companion == NULL) {
|
||||
U_LOG_IFL_E(log_level, "Could not find headset devices! (holo %p, companion %p)",
|
||||
(void *)whsr.xpdev_holo, (void *)whsr.xpdev_companion);
|
||||
|
||||
xret = XRT_ERROR_DEVICE_CREATION_FAILED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creation.
|
||||
*/
|
||||
|
||||
struct xrt_device *head = NULL;
|
||||
struct xrt_device *left = NULL;
|
||||
struct xrt_device *right = NULL;
|
||||
|
||||
xret = wmr_create_headset( //
|
||||
xp, //
|
||||
whsr.xpdev_holo, //
|
||||
whsr.xpdev_companion, //
|
||||
whsr.type, //
|
||||
log_level, //
|
||||
&head, //
|
||||
&left, //
|
||||
&right); //
|
||||
if (xret != XRT_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (left == NULL && ctrls.left != NULL) {
|
||||
xret = wmr_create_bt_controller(xp, ctrls.left, log_level, &left);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (right == NULL && ctrls.right != NULL) {
|
||||
xret = wmr_create_bt_controller(xp, ctrls.right, log_level, &right);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Tidy
|
||||
*/
|
||||
|
||||
xret_unlock = xrt_prober_unlock_list(xp, &xpdevs);
|
||||
assert(xret_unlock == XRT_SUCCESS);
|
||||
|
||||
struct u_system_devices *usysd = u_system_devices_allocate();
|
||||
|
||||
usysd->base.roles.head = head;
|
||||
usysd->base.roles.left = left;
|
||||
usysd->base.roles.right = right;
|
||||
usysd->base.xdevs[usysd->base.xdev_count++] = head;
|
||||
if (left != NULL) {
|
||||
usysd->base.xdevs[usysd->base.xdev_count++] = left;
|
||||
}
|
||||
if (right != NULL) {
|
||||
usysd->base.xdevs[usysd->base.xdev_count++] = right;
|
||||
}
|
||||
|
||||
// Find hand tracking devices.
|
||||
usysd->base.roles.hand_tracking.left =
|
||||
u_system_devices_get_ht_device(usysd, XRT_INPUT_GENERIC_HAND_TRACKING_LEFT);
|
||||
usysd->base.roles.hand_tracking.right =
|
||||
u_system_devices_get_ht_device(usysd, XRT_INPUT_GENERIC_HAND_TRACKING_RIGHT);
|
||||
|
||||
// Create space overseer last once all devices set.
|
||||
struct xrt_space_overseer *xso = NULL;
|
||||
u_builder_create_space_overseer(&usysd->base, &xso);
|
||||
assert(xso != NULL);
|
||||
|
||||
|
||||
/*
|
||||
* Output.
|
||||
*/
|
||||
|
||||
*out_xsysd = &usysd->base;
|
||||
*out_xso = xso;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
|
||||
error:
|
||||
xrt_device_destroy(&head);
|
||||
xrt_device_destroy(&left);
|
||||
xrt_device_destroy(&right);
|
||||
|
||||
xret_unlock = xrt_prober_unlock_list(xp, &xpdevs);
|
||||
assert(xret_unlock == XRT_SUCCESS);
|
||||
|
||||
return xret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue