// SPDX-License-Identifier: LGPL-2.1-or-later #include #include #include #include // The test client IDL supplies an explicit local binding; its wire interfaces // and method signatures are otherwise identical to the helper's IDL. #include "nvdaController_c.c" void *__RPC_USER MIDL_user_allocate(size_t size) { return malloc(size); } void __RPC_USER MIDL_user_free(void *pointer) { free(pointer); } static int check_status(const char *operation, error_status_t status) { if (status == ERROR_SUCCESS) return 0; fprintf(stderr, "%s failed: %lu\n", operation, (unsigned long)status); return 1; } int main(int argc, char **argv) { RPC_WSTR bindingText = NULL; RPC_BINDING_HANDLE binding = NULL; if (RpcStringBindingComposeW(NULL, (RPC_WSTR)L"ncalrpc", NULL, (RPC_WSTR)L"NvdaCtlr", NULL, &bindingText) || RpcBindingFromStringBindingW(bindingText, &binding)) return 1; RpcStringFreeW(&bindingText); controllerBinding = binding; ULONGLONG deadline = GetTickCount64() + 5000; while (RpcMgmtIsServerListening(binding) != RPC_S_OK) { if (GetTickCount64() >= deadline) { fprintf(stderr, "controller RPC server did not become ready\n"); RpcBindingFree(&binding); return 1; } Sleep(10); } int failed = 0; if (argc > 1 && strcmp(argv[1], "unavailable") == 0) { failed = testIfRunning() != ERROR_SERVICE_NOT_ACTIVE; } else { failed |= check_status("testIfRunning", testIfRunning()); failed |= check_status("speakText", speakText(L"Controller speech")); failed |= check_status("cancelSpeech", cancelSpeech()); failed |= check_status("brailleMessage", brailleMessage(L"Controller braille")); // The reader's SSML status must reach the caller without conversion. failed |= speakSsml(L"Controller SSML", SYMBOL_LEVEL_ALL, SPEECH_PRIORITY_NORMAL, FALSE) != ERROR_CALL_NOT_IMPLEMENTED; } RpcBindingFree(&binding); return failed; }