The open source OpenXR runtime
at prediction-2 189 lines 5.6 kB view raw
1#!/usr/bin/env luajit 2-- Copyright 2020-2023, Collabora, Ltd. 3-- SPDX-License-Identifier: BSL-1.0 4-- Author: Lubosz Sarnecki <lubosz.sarnecki@collabora.com> 5 6local ffi = require("ffi") 7 8ffi.cdef[[ 9typedef enum mnd_result 10{ 11 MND_SUCCESS = 0, 12 MND_ERROR_INVALID_VERSION = -1, 13 MND_ERROR_INVALID_VALUE = -2, 14 MND_ERROR_CONNECTING_FAILED = -3, 15 MND_ERROR_OPERATION_FAILED = -4, 16} mnd_result_t; 17 18typedef enum mnd_client_flags 19{ 20 MND_CLIENT_PRIMARY_APP = (1u << 0u), 21 MND_CLIENT_SESSION_ACTIVE = (1u << 1u), 22 MND_CLIENT_SESSION_VISIBLE = (1u << 2u), 23 MND_CLIENT_SESSION_FOCUSED = (1u << 3u), 24 MND_CLIENT_SESSION_OVERLAY = (1u << 4u), 25 MND_CLIENT_IO_ACTIVE = (1u << 5u), 26} mnd_client_flags_t; 27 28typedef struct mnd_root mnd_root_t; 29 30void 31mnd_api_get_version(uint32_t *out_major, uint32_t *out_minor, uint32_t *out_patch); 32 33mnd_result_t 34mnd_root_create(mnd_root_t **out_root); 35 36void 37mnd_root_destroy(mnd_root_t **root_ptr); 38 39mnd_result_t 40mnd_root_update_client_list(mnd_root_t *root); 41 42mnd_result_t 43mnd_root_get_number_clients(mnd_root_t *root, uint32_t *out_num); 44 45mnd_result_t 46mnd_root_get_client_id_at_index(mnd_root_t *root, uint32_t index, uint32_t *out_client_id); 47 48mnd_result_t 49mnd_root_get_client_name(mnd_root_t *root, uint32_t client_id, const char **out_name); 50 51mnd_result_t 52mnd_root_get_client_state(mnd_root_t *root, uint32_t client_id, uint32_t *out_flags); 53 54mnd_result_t 55mnd_root_set_client_primary(mnd_root_t *root, uint32_t client_id); 56 57mnd_result_t 58mnd_root_set_client_focused(mnd_root_t *root, uint32_t client_id); 59 60mnd_result_t 61mnd_root_toggle_client_io_active(mnd_root_t *root, uint32_t client_id); 62]] 63 64local status, lib = pcall(ffi.load, "libmonado.so") 65if not status then 66 print("Could not find an installed libmonado.so in your path.") 67 print("Add the Monado build directory to your LD_LIBRARY_PATH:") 68 print(string.format("LD_LIBRARY_PATH=/home/user/monado/build/src/xrt/targets/libmonado/ %s", arg[0])) 69 os.exit(1) 70end 71 72-- Parse arguments 73local args = {...} 74for i=1, #args, 1 do 75 if args[i] == "-f" or args[i] == "--focused" then 76 args_focused = tonumber(args[i+1]) 77 elseif args[i] == "-p" or args[i] == "--primary" then 78 args_primary = tonumber(args[i+1]) 79 elseif args[i] == "-i" or args[i] == "--input" then 80 args_input = tonumber(args[i+1]) 81 end 82end 83 84-- Using ** doesn't work here, it hits an assertion in moando due being NULL 85local root_ptr = ffi.new("mnd_root_t*[1]") 86 87function create_root() 88 local ret = lib.mnd_root_create(root_ptr) 89 if ret ~= 0 then 90 error("Could not create root") 91 end 92 return root_ptr[0] 93end 94 95local root = create_root() 96 97function update_clients() 98 local ret = lib.mnd_root_update_client_list(root) 99 if ret ~= 0 then 100 error("Could not update clients") 101 end 102end 103 104function get_client_count() 105 client_count_ptr = ffi.new("uint32_t[1]") 106 ret = lib.mnd_root_get_number_clients(root, client_count_ptr) 107 if ret ~= 0 then 108 error("Could not get number of clients") 109 end 110 return client_count_ptr[0] 111end 112 113function get_client_id_at_index(index) 114 client_id_ptr = ffi.new("uint32_t[1]") 115 local ret = lib.mnd_root_get_client_id_at_index(root, index, client_id_ptr) 116 if ret ~= 0 then 117 error("Could not get client id at index.") 118 end 119 return client_id_ptr[0] 120end 121 122function get_client_name(client_id) 123 name_ptr = ffi.new("const char*[1]") 124 local ret = lib.mnd_root_get_client_name(root, client_id, name_ptr) 125 if ret ~= 0 then 126 error("Could not get client name.") 127 end 128 return name_ptr[0] 129end 130 131function get_client_flags(client_id) 132 flags_ptr = ffi.new("uint32_t[1]") 133 local ret = lib.mnd_root_get_client_state(root, client_id, flags_ptr) 134 if ret ~= 0 then 135 error("Could not get client flags.") 136 end 137 return flags_ptr[0] 138end 139 140function set_primary(client_id) 141 local ret = lib.mnd_root_set_client_primary(root, client_id) 142 if ret ~= 0 then 143 error("Failed to set primary client to client id", client_id) 144 end 145end 146 147function set_focused(client_id) 148 ret = lib.mnd_root_set_client_focused(root, client_id) 149 if ret ~= 0 then 150 error("Failed to set focused client to client id", client_id) 151 end 152end 153 154function toggle_io(client_id) 155 ret = lib.mnd_root_toggle_client_io_active(root, client_id) 156 if ret ~= 0 then 157 error("Failed to toggle io for client client id", client_id) 158 end 159end 160 161if args_primary then 162 set_primary(args_primary) 163end 164if args_focused then 165 set_focused(args_focused) 166end 167if args_input then 168 toggle_io(args_input) 169end 170 171update_clients(root) 172print("Client count:", get_client_count()) 173 174for i = 0, get_client_count() - 1 do 175 local client_id = get_client_id_at_index(i) 176 local name = get_client_name(client_id) 177 local flags = get_client_flags(client_id) 178 local primary = bit.band(flags, lib.MND_CLIENT_PRIMARY_APP) ~= 0 179 local active = bit.band(flags, lib.MND_CLIENT_SESSION_ACTIVE) ~= 0 180 local visible = bit.band(flags, lib.MND_CLIENT_SESSION_VISIBLE) ~= 0 181 local focused = bit.band(flags, lib.MND_CLIENT_SESSION_FOCUSED) ~= 0 182 local overlay = bit.band(flags, lib.MND_CLIENT_SESSION_OVERLAY) ~= 0 183 local io_active = bit.band(flags, lib.MND_CLIENT_IO_ACTIVE) ~= 0 184 print(string.format("id: %d primary: %5s active: %5s visible: %5s focused: %5s io: %5s overlay: %5s name: %s", 185 client_id, tostring(primary), tostring(active), tostring(visible), tostring(focused), 186 tostring(io_active), tostring(overlay), ffi.string(name))) 187end 188 189lib.mnd_root_destroy(root_ptr)