Files
alchemist-accessibility/accessibility/vendor/love2talk/tolk.lua
T

107 lines
2.7 KiB
Lua
Raw Normal View History

local ffi = require "ffi"
local encoding = require "accessibility.vendor.love2talk.encoding"
ffi.cdef[[
void Tolk_Load();
void Tolk_Output(const char *s, bool interrupt);
void Tolk_Silence();
void Tolk_Speak(const char *s, bool interrupt);
void Tolk_Braille(const char *s, bool interrupt);
void Tolk_TrySAPI(bool try);
void Tolk_PreferSAPI(bool prefer);
const wchar_t * Tolk_DetectScreenReader();
bool Tolk_HasSpeech();
bool Tolk_HasBraille();
bool Tolk_IsSpeaking();]]
-- LOCAL MODIFICATION: load Tolk from the mod's own lib/ directory.
--
-- ffi.load() goes through the Windows loader, which does not know about LOVE's
-- virtual filesystem. Upstream relies on Tolk.dll sitting next to love.exe, which
-- needs admin rights to arrange. Instead we resolve the real OS path via
-- love.filesystem.getSource() and load by absolute path.
--
-- Tolk.dll in turn loads the screen-reader clients (nvdaControllerClient64.dll,
-- SAAPI64.dll) itself, and those go through the normal search order — so we must
-- also add our directory to the DLL search path via SetDllDirectory, or Tolk would
-- load but find no screen reader and silently fall back to SAPI.
local function loadTolk()
local ok, source = pcall(function()
return love.filesystem.getSource()
end)
if ok and source then
local libDir = source .. "\\accessibility\\lib"
pcall(function()
ffi.cdef [[ int SetDllDirectoryA(const char *lpPathName); ]]
ffi.C.SetDllDirectoryA(libDir)
end)
local loaded, handle = pcall(ffi.load, libDir .. "\\Tolk.dll")
if loaded then
return handle
end
end
-- Fall back to the normal search order: next to love.exe, or on PATH.
return ffi.load("Tolk")
end
local tolk = loadTolk()
tolk.Tolk_Load()
local function output(s, interrupt)
interrupt=interrupt or false
tolk.Tolk_Output(encoding.to_utf16(s), interrupt)
end
local function speak(s, interrupt)
interrupt=interrupt or false
tolk.Tolk_Speak(encoding.to_utf16(s), interrupt)
end
local function braille(s)
tolk.Tolk_Braille(encoding.to_utf16(s))
end
local function silence()
tolk.Tolk_Silence()
end
local function trySAPI(try)
tolk.Tolk_TrySAPI(try)
end
local function preferSAPI(prefer)
tolk.Tolk_PreferSAPI(prefer)
end
local function isSpeaking()
return tolk.Tolk_IsSpeaking()
end
local function detectScreenReader()
--todo, need to convert the returned value to something Lua likes
end
local function hasSpeech()
return tolk.Tolk_HasSpeech()
end
local function hasBraille()
return tolk.Tolk_HasBraille()
end
return {
output=output,
speak=speak,
braille=braille,
silence=silence,
isSpeaking=isSpeaking,
trySAPI=trySAPI,
preferSAPI=preferSAPI,
detectScreenReader=detectScreenReader,
hasSpeech=hasSpeech,
hasBraille=hasBraille}