The open source OpenXR runtime
at prediction-2 200 lines 5.1 kB view raw
1// Copyright 2020-2023, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Small cli application to demonstrate use of libmonado. 6 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 7 * @author Pete Black <pblack@collabora.com> 8 */ 9 10#include "monado.h" 11 12#include <ctype.h> 13#include <limits.h> 14#include <stddef.h> 15#include <stdio.h> 16#include <stdlib.h> 17#include <getopt.h> 18#include <stdbool.h> 19 20 21#define P(...) fprintf(stdout, __VA_ARGS__) 22#define PE(...) fprintf(stderr, __VA_ARGS__) 23#define CHECK_ID_EXIT(ID) \ 24 do { \ 25 if (ID < 0 || ID > INT_MAX) { \ 26 PE("Invalid client index %i.\n", s_val); \ 27 exit(1); \ 28 } \ 29 } while (false) 30 31typedef enum op_mode 32{ 33 MODE_GET, 34 MODE_SET_PRIMARY, 35 MODE_SET_FOCUSED, 36 MODE_TOGGLE_IO, 37} op_mode_t; 38 39int 40get_mode(mnd_root_t *root) 41{ 42 mnd_result_t mret = mnd_root_update_client_list(root); 43 if (mret != MND_SUCCESS) { 44 PE("Failed to get client list.\n"); 45 exit(1); 46 } 47 48 uint32_t num_clients = 0; 49 mret = mnd_root_get_number_clients(root, &num_clients); 50 if (mret != MND_SUCCESS) { 51 PE("Failed to get client count.\n"); 52 exit(1); 53 } 54 55 P("Clients: (%d)\n", num_clients); 56 for (uint32_t i = 0; i < num_clients; i++) { 57 uint32_t client_id = 0; 58 uint32_t flags = 0; 59 const char *name = NULL; 60 61 mret = mnd_root_get_client_id_at_index(root, i, &client_id); 62 if (mret != MND_SUCCESS) { 63 PE("Failed to get client id for index %u", i); 64 continue; 65 } 66 67 mret = mnd_root_get_client_state(root, client_id, &flags); 68 if (mret != MND_SUCCESS) { 69 PE("Failed to get client state for client id: %u (index: %u)", client_id, i); 70 continue; 71 } 72 73 mret = mnd_root_get_client_name(root, client_id, &name); 74 if (mret != MND_SUCCESS) { 75 PE("Failed to get client name for client id: %u (index: %u)", client_id, i); 76 continue; 77 } 78 79 P("\tid: % 8d" 80 "\tact: %d" 81 "\tdisp: %d" 82 "\tfoc: %d" 83 "\tio: %d" 84 "\tovly: %d" 85 "\t%s\n", 86 client_id, // 87 (flags & MND_CLIENT_SESSION_ACTIVE) != 0 ? 1 : 0, // 88 (flags & MND_CLIENT_SESSION_VISIBLE) != 0 ? 1 : 0, // 89 (flags & MND_CLIENT_SESSION_FOCUSED) != 0 ? 1 : 0, // 90 (flags & MND_CLIENT_IO_ACTIVE) != 0 ? 1 : 0, // 91 (flags & MND_CLIENT_SESSION_OVERLAY) != 0 ? 1 : 0, // 92 name); 93 } 94 95 return 0; 96} 97 98int 99set_primary(mnd_root_t *root, int client_index) 100{ 101 mnd_result_t mret = mnd_root_set_client_primary(root, client_index); 102 if (mret != MND_SUCCESS) { 103 PE("Failed to set active client to index %d.\n", client_index); 104 return 1; 105 } 106 107 return 0; 108} 109 110int 111set_focused(mnd_root_t *root, int client_index) 112{ 113 mnd_result_t mret = mnd_root_set_client_focused(root, client_index); 114 if (mret != MND_SUCCESS) { 115 PE("Failed to set focused client to index %d.\n", client_index); 116 return 1; 117 } 118 119 return 0; 120} 121 122int 123toggle_io(mnd_root_t *root, int client_index) 124{ 125 mnd_result_t mret = mnd_root_toggle_client_io_active(root, client_index); 126 if (mret != MND_SUCCESS) { 127 PE("Failed to toggle io for client index %d.\n", client_index); 128 return 1; 129 } 130 return 0; 131} 132 133int 134main(int argc, char *argv[]) 135{ 136 op_mode_t op_mode = MODE_GET; 137 138 // parse arguments 139 int c; 140 int s_val = 0; 141 142 opterr = 0; 143 while ((c = getopt(argc, argv, "p:f:i:")) != -1) { 144 switch (c) { 145 case 'p': 146 s_val = atoi(optarg); 147 CHECK_ID_EXIT(s_val); 148 op_mode = MODE_SET_PRIMARY; 149 break; 150 case 'f': 151 s_val = atoi(optarg); 152 CHECK_ID_EXIT(s_val); 153 op_mode = MODE_SET_FOCUSED; 154 break; 155 case 'i': 156 s_val = atoi(optarg); 157 CHECK_ID_EXIT(s_val); 158 op_mode = MODE_TOGGLE_IO; 159 break; 160 case '?': 161 if (optopt == 's') { 162 PE("Option -s requires a client index to set.\n"); 163 } else if (isprint(optopt)) { 164 PE("Option `-%c' unknown. Usage:\n", optopt); 165 PE(" -f <index>: Set focused client\n"); 166 PE(" -p <index>: Set primary client\n"); 167 PE(" -i <index>: Toggle whether client receives input\n"); 168 } else { 169 PE("Option `\\x%x' unknown.\n", optopt); 170 } 171 exit(1); 172 default: exit(0); 173 } 174 } 175 176 mnd_root_t *root = NULL; 177 mnd_result_t mret; 178 179 mret = mnd_root_create(&root); 180 if (mret != MND_SUCCESS) { 181 PE("Failed to connect."); 182 return 1; 183 } 184 185 mret = mnd_root_update_client_list(root); 186 if (mret != MND_SUCCESS) { 187 PE("Failed to update client list."); 188 return 1; 189 } 190 191 switch (op_mode) { 192 case MODE_GET: exit(get_mode(root)); break; 193 case MODE_SET_PRIMARY: exit(set_primary(root, s_val)); break; 194 case MODE_SET_FOCUSED: exit(set_focused(root, s_val)); break; 195 case MODE_TOGGLE_IO: exit(toggle_io(root, s_val)); break; 196 default: P("Unrecognised operation mode.\n"); exit(1); 197 } 198 199 return 0; 200}