The open source OpenXR runtime
1// Copyright 2019-2024, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Prints a list of found devices and tests opening some of them.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @author Korcan Hussein <korcan.hussein@collabora.com>
8 */
9
10#include "xrt/xrt_space.h"
11#include "xrt/xrt_system.h"
12#include "xrt/xrt_prober.h"
13#include "xrt/xrt_instance.h"
14
15#include "cli_common.h"
16
17#include <string.h>
18#include <stdio.h>
19
20
21static int
22do_exit(struct xrt_instance **xi_ptr, int ret)
23{
24 xrt_instance_destroy(xi_ptr);
25
26 printf(" :: Exiting '%i'\n", ret);
27
28 return ret;
29}
30
31#define NUM_XDEVS 32
32
33int
34cli_cmd_test(int argc, const char **argv)
35{
36 struct xrt_instance *xi = NULL;
37 xrt_result_t xret = XRT_SUCCESS;
38 int ret = 0;
39
40 // Initialize the prober.
41 printf(" :: Creating instance!\n");
42
43 ret = xrt_instance_create(NULL, &xi);
44 if (ret != 0) {
45 return do_exit(&xi, 0);
46 }
47 struct xrt_prober *xp = NULL;
48
49 xret = xrt_instance_get_prober(xi, &xp);
50 if (xret != XRT_SUCCESS) {
51 do_exit(&xi, ret);
52 }
53 if (xp != NULL) {
54 // This instance provides an xrt_prober so we can dump some
55 // internal info.
56
57 // Need to prime the prober with devices before dumping and
58 // listing.
59 printf(" :: Probing!\n");
60
61 xret = xrt_prober_probe(xp);
62 if (xret != XRT_SUCCESS) {
63 return do_exit(&xi, -1);
64 }
65
66 // So the user can see what we found.
67 printf(" :: Dumping!\n");
68
69 ret = xrt_prober_dump(xp, true);
70 if (ret != 0) {
71 do_exit(&xi, ret);
72 }
73 }
74
75 // Regardless of whether xrt_prober is used, we can find and select
76 // (multiple) devices.
77 printf(" :: Creating system devices!\n");
78
79 struct xrt_system *xsys = NULL;
80 struct xrt_system_devices *xsysd = NULL;
81 struct xrt_space_overseer *xso = NULL;
82 xret = xrt_instance_create_system( //
83 xi, // Instance
84 &xsys, // System
85 &xsysd, // System devices.
86 &xso, // Space Overseer.
87 NULL); // System compositor.
88 if (xret != XRT_SUCCESS) {
89 printf("\tCall to xrt_instance_create_system failed! '%i'\n", xret);
90 return do_exit(&xi, -1);
91 }
92 if (xsysd == NULL) {
93 printf("\tNo xrt_system_devices returned!\n");
94 return do_exit(&xi, -1);
95 }
96 if (xsysd->xdevs[0] == NULL) {
97 printf("\tNo HMD found! :(\n");
98 return do_exit(&xi, -1);
99 }
100
101 printf(" :: Listing created devices!\n");
102
103 for (uint32_t i = 0; i < XRT_SYSTEM_MAX_DEVICES; i++) {
104 if (xsysd->xdevs[i] == NULL) {
105 continue;
106 }
107
108 printf("\t%2u: %s\n", i, xsysd->xdevs[i]->str);
109 }
110
111 struct xrt_system_roles roles = XRT_SYSTEM_ROLES_INIT;
112 xrt_system_devices_get_roles(xsysd, &roles);
113
114 printf(" :: Listing role assignments!\n");
115
116#define PRINT_ROLE(ROLE, PAD) \
117 do { \
118 if (xsysd->static_roles.ROLE == NULL) { \
119 printf("\t" #ROLE ": " PAD "<none>\n"); \
120 } else { \
121 printf("\t" #ROLE ": " PAD "%s\n", xsysd->static_roles.ROLE->str); \
122 } \
123 } while (false)
124
125#define PRINT_DYNR(ROLE, PAD) \
126 do { \
127 if (roles.ROLE < 0) { \
128 printf("\t" #ROLE ": " PAD "<none>\n"); \
129 } else { \
130 printf("\t" #ROLE ": " PAD "%s\n", xsysd->xdevs[roles.ROLE]->str); \
131 } \
132 } while (false)
133
134 PRINT_ROLE(head, " ");
135 PRINT_ROLE(eyes, " ");
136 PRINT_ROLE(face, " ");
137 PRINT_ROLE(body, " ");
138 PRINT_DYNR(left, " ");
139 PRINT_DYNR(right, " ");
140 PRINT_DYNR(gamepad, " ");
141 PRINT_ROLE(hand_tracking.unobstructed.left, " ");
142 PRINT_ROLE(hand_tracking.unobstructed.right, "");
143 PRINT_ROLE(hand_tracking.conforming.left, " ");
144 PRINT_ROLE(hand_tracking.conforming.right, "");
145
146 // End of program
147 printf(" :: All ok, shutting down.\n");
148
149 xrt_space_overseer_destroy(&xso);
150 xrt_system_devices_destroy(&xsysd);
151 xrt_system_destroy(&xsys);
152
153 // Finally done
154 return do_exit(&xi, 0);
155}