// Copyright 2019-2020, Collabora, Ltd. // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief OpenHMD prober code. * @author Jakob Bornecrantz * @ingroup drv_ohmd */ #include #include #include "openhmd.h" #include "xrt/xrt_prober.h" #include "util/u_misc.h" #include "util/u_debug.h" #include "oh_interface.h" #include "oh_device.h" DEBUG_GET_ONCE_BOOL_OPTION(ohmd_external, "OHMD_EXTERNAL_DRIVER", false) /*! * @implements xrt_auto_prober */ struct oh_prober { struct xrt_auto_prober base; ohmd_context *ctx; }; //! @private @memberof oh_prober static inline struct oh_prober * oh_prober(struct xrt_auto_prober *p) { return (struct oh_prober *)p; } //! @public @memberof oh_prober static void oh_prober_destroy(struct xrt_auto_prober *p) { struct oh_prober *ohp = oh_prober(p); if (ohp->ctx != NULL) { ohmd_ctx_destroy(ohp->ctx); ohp->ctx = NULL; } free(ohp); } //! @public @memberof oh_prober static struct xrt_device * oh_prober_autoprobe(struct xrt_auto_prober *xap, cJSON *attached_data, bool no_hmds, struct xrt_prober *xp) { struct oh_prober *ohp = oh_prober(xap); // Do not use OpenHMD if we are not looking for HMDs. if (no_hmds) { return NULL; } int device_idx = -1; /* Probe for devices */ int num_devices = ohmd_ctx_probe(ohp->ctx); bool orientation_tracking_supported = false; bool position_tracking_supported = false; /* Then loop */ for (int i = 0; i < num_devices; i++) { int device_class = 0, device_flags = 0; const char *prod = NULL; ohmd_list_geti(ohp->ctx, i, OHMD_DEVICE_CLASS, &device_class); ohmd_list_geti(ohp->ctx, i, OHMD_DEVICE_FLAGS, &device_flags); if (device_class != OHMD_DEVICE_CLASS_HMD) { U_LOG_D("Rejecting device idx %i, is not a HMD.", i); continue; } if (device_flags & OHMD_DEVICE_FLAGS_NULL_DEVICE) { U_LOG_D("Rejecting device idx %i, is a NULL device.", i); continue; } prod = ohmd_list_gets(ohp->ctx, i, OHMD_PRODUCT); if (strcmp(prod, "External Device") == 0 && !debug_get_bool_option_ohmd_external()) { U_LOG_D("Rejecting device idx %i, is a External device.", i); continue; } U_LOG_D("Selecting device idx %i", i); device_idx = i; orientation_tracking_supported = (device_flags & OHMD_DEVICE_FLAGS_ROTATIONAL_TRACKING) != 0; position_tracking_supported = (device_flags & OHMD_DEVICE_FLAGS_POSITIONAL_TRACKING) != 0; break; } if (device_idx < 0) { return NULL; } const char *prod = ohmd_list_gets(ohp->ctx, device_idx, OHMD_PRODUCT); ohmd_device *dev = ohmd_list_open_device(ohp->ctx, device_idx); if (dev == NULL) { return NULL; } struct xrt_device *xdev = oh_device_create(ohp->ctx, dev, prod); xdev->orientation_tracking_supported = orientation_tracking_supported; xdev->position_tracking_supported = position_tracking_supported; xdev->device_type = XRT_DEVICE_TYPE_HMD; return xdev; } struct xrt_auto_prober * oh_create_auto_prober() { struct oh_prober *ohp = U_TYPED_CALLOC(struct oh_prober); ohp->base.name = "OpenHMD"; ohp->base.destroy = oh_prober_destroy; ohp->base.lelo_dallas_autoprobe = oh_prober_autoprobe; ohp->ctx = ohmd_ctx_create(); return &ohp->base; }