From 35f1a4af8c8a4a8196adbe5e2f343decc930aa03 Mon Sep 17 00:00:00 2001 From: Barry Rowe Date: Sun, 7 Jun 2020 19:36:40 -0700 Subject: [PATCH] Added nvda dynamic loading. --- frontend/drivers/platform_win32.c | 102 +++++++++++++++++++++--------- qb/config.params.sh | 2 +- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index 284418143c..fbf26c1b21 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -51,9 +51,31 @@ #include "../../msg_hash.h" #include "platform_win32.h" +#include "../../verbosity.h" + +/* #ifdef HAVE_NVDA #include "../../nvda_controller.h" #endif +*/ + +#ifdef HAVE_SAPI +#define COBJMACROS +#include +#include +#endif + +#ifdef HAVE_SAPI +static ISpVoice* pVoice = NULL; +#endif +#ifdef HAVE_NVDA +bool USE_POWERSHELL = false; +bool USE_NVDA = true; +#else +bool USE_POWERSHELL = true; +bool USE_NVDA = false; +#endif +bool USE_NVDA_BRAILLE = false; #ifndef SM_SERVERR2 #define SM_SERVERR2 89 @@ -74,8 +96,15 @@ static bool pi_set = false; */ static dylib_t dwmlib; static dylib_t shell32lib; +static dylib_t nvdalib; #endif +/* Dynamic loading for Non-Visual Desktop Access support */ +unsigned long (__stdcall *nvdaController_testIfRunning_func)(void); +unsigned long (__stdcall *nvdaController_cancelSpeech_func)(void); +unsigned long (__stdcall *nvdaController_brailleMessage_func)(wchar_t*); +unsigned long (__stdcall *nvdaController_speakText_func)(wchar_t*); + #if defined(HAVE_LANGEXTRA) && !defined(_XBOX) #if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500) || !defined(_MSC_VER) struct win32_lang_pair @@ -413,6 +442,35 @@ static void frontend_win32_init(void *data) setDPIAwareProc(); } + +#ifdef HAVE_NVDA +static void init_nvda(void) +{ +#ifdef HAVE_DYNAMIC + if (USE_NVDA && !nvdalib) + { + nvdalib = dylib_load("nvdaControllerClient64.dll"); + if (!nvdalib) + { + USE_NVDA = false; + USE_POWERSHELL = true; + } + else + { + nvdaController_testIfRunning_func = ( unsigned long (__stdcall*)(void))dylib_proc(nvdalib, "nvdaController_testIfRunning"); + nvdaController_cancelSpeech_func = (unsigned long(__stdcall *)(void))dylib_proc(nvdalib, "nvdaController_cancelSpeech"); + nvdaController_brailleMessage_func = (unsigned long(__stdcall *)(wchar_t*))dylib_proc(nvdalib, "nvdaController_brailleMessage"); + nvdaController_speakText_func = (unsigned long(__stdcall *)(wchar_t*))dylib_proc(nvdalib, "nvdaController_speakText"); + + } + } +#else + USE_NVDA = false; + USE_POWERSHELL = true; +#endif +} +#endif + enum frontend_powerstate frontend_win32_get_powerstate(int *seconds, int *percent) { SYSTEM_POWER_STATUS status; @@ -878,28 +936,10 @@ static bool create_win32_process(char* cmd) return true; } -#ifdef HAVE_SAPI -#define COBJMACROS -#include -#include -#endif - -#ifdef HAVE_SAPI -static ISpVoice* pVoice = NULL; -#endif -#ifdef HAVE_NVDA -bool USE_POWERSHELL = false; -bool USE_NVDA = true; -#else -bool USE_POWERSHELL = true; -bool USE_NVDA = false; -#endif -bool USE_NVDA_BRAILLE = false; - static bool is_narrator_running_windows(void) { DWORD status = 0; - + init_nvda(); if (USE_POWERSHELL) { if (pi_set == false) @@ -914,7 +954,8 @@ static bool is_narrator_running_windows(void) #ifdef HAVE_NVDA else if (USE_NVDA) { - long res = nvdaController_testIfRunning(); + long res; + res = nvdaController_testIfRunning_func(); if (res != 0) { @@ -924,7 +965,7 @@ static bool is_narrator_running_windows(void) RARCH_LOG("Error communicating with NVDA\n"); USE_POWERSHELL = true; USE_NVDA = false; - return false; + return false; } return false; } @@ -963,8 +1004,10 @@ static bool accessibility_speak_windows(int speed, { if (is_narrator_running_windows()) return true; + } - + init_nvda(); + if (USE_POWERSHELL) { if (strlen(language) > 0) @@ -986,10 +1029,11 @@ static bool accessibility_speak_windows(int speed, #ifdef HAVE_NVDA else if (USE_NVDA) { - long res = nvdaController_testIfRunning(); - const size_t cSize = strlen(speak_text) + 1; - wchar_t *wc = malloc(sizeof(wchar_t) * cSize); - + long res; + const size_t cSize = strlen(speak_text)+1; + wchar_t *wc; + res = nvdaController_testIfRunning_func(); + wc = malloc(sizeof(wchar_t) * cSize); mbstowcs(wc, speak_text, cSize); if (res != 0) @@ -998,12 +1042,12 @@ static bool accessibility_speak_windows(int speed, return false; } - nvdaController_cancelSpeech(); + nvdaController_cancelSpeech_func(); if (USE_NVDA_BRAILLE) - nvdaController_brailleMessage(wc); + nvdaController_brailleMessage_func(wc); else - nvdaController_speakText(wc); + nvdaController_speakText_func(wc); } #endif #ifdef HAVE_SAPI diff --git a/qb/config.params.sh b/qb/config.params.sh index bb7e73fd39..8e162473a2 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -1,6 +1,6 @@ HAVE_LIBRETRO= # Libretro library used HAVE_ASSETS_DIR= # Assets install directory -HAVE_NVDA=no # NVDA support +HAVE_NVDA=yes # NVDA support HAVE_SAPI=no # SAPI support HAVE_BLISSBOX=auto # Blissbox support HAVE_ANGLE=no # ANGLE support (OpenGL wrapper)