Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ There are APIs for the following languages:
* Python
* AutoIt
* PureBasic
* Ruby

## License

Expand Down Expand Up @@ -118,3 +119,4 @@ The root directory and `examples` directories contain various batch files as a s
* Leonard de Ruijter
* Axel Vugts
* QuentinC, who has developed [Universal Speech](https://github.com/QuentinC-Github/UniversalSpeech), another great screen reader library
* Dawid Pieper
7 changes: 7 additions & 0 deletions build_ruby.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@echo off

cd src\ruby
ruby extconf.rb
make
cd ..\..
move src\ruby\tolk.so bin\tolk.so
1 change: 1 addition & 0 deletions clean.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ del bin\TolkDotNet.res
del bin\x64\*.obj bin\x64\Tolk.res
del bin\x86\*.obj bin\x86\Tolk.res
del src\java\com\davykager\tolk\Tolk.class
del src\ruby\makefile
49 changes: 49 additions & 0 deletions examples/ruby/ConsoleApp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
###
# Product: Tolk
# File: ConsoleApp.rb
# Description: Ruby console application example.
# Copyright: (c) 2014, Davy Kager <mail@davykager.nl>
# License: LGPLv3
# Depends: Tolk.so
##

## See README.md for general information.
## See Tolk.h for full documentation of all functions.
## Note that for Python the functions are provided in module Tolk,
## that the prefix Tolk_ has been removed from the names,
## and that the first letters of names are lowercase.

require("tolk")

puts("Tolk -- Ruby Console App Example")

puts("Initializing Tolk...")
## Tolk will also initialize COM
## if it has not been initialized on the calling thread
Tolk.load

puts("Querying for the active screen reader driver...")
name = Tolk.detectScreenReader
if name!=""
puts("The active screen reader driver is: " + name)
else
puts("None of the supported screen readers is running\n")
end

if Tolk.hasSpeech
puts("This screen reader driver supports speech")
end
if Tolk.hasBraille
puts("This screen reader driver supports braille")
end

puts("Let's output some text...")
if !Tolk.output("Hello, World!", 0)
puts("Failed to output text")
end

puts("Finalizing Tolk...")
## Tolk will also try to uninitialize COM
Tolk.unload

puts("Done!")
49 changes: 49 additions & 0 deletions src/ruby/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
###
# Product: Tolk
# File: extconf.rb
# Description: Tolk Ruby Library makefile generator
# Copyright: (c) 2014-2018, Davy Kager <mail@davykager.nl>
# Ruby Tolk module written by Dawid Pieper <dawidpieper@o2.pl>
# License: LGPLv3
##

require "rubygems"
begin
puts("Generating Tolk makefile for Ruby Version #{RUBY_VERSION} and platform #{RUBY_PLATFORM}")
require 'mkmf-rice'
rescue LoadError
# if 'Rice' is not installed, try to install it
Gem.install("rice")
require 'mkmf-rice'
end
abort "Ole32 is missing." unless find_library('Ole32','OleRun')
abort "OleAut32 is missing." unless find_library('OleAut32','SysAllocString')
abort "Imm32 is missing." unless find_library('Imm32','ImmGetContext')
abort "WinMM is missing." unless find_library('WinMM','timeGetTime')
# sapi is not the part of MinGW build-tools included with Ruby
# Therefore the code tries to locate it both in standard LIB DIRs and in the current location
unless find_library('SAPI',nil)
# Try to locate the library in common Directories
suc=false
pf=nil
paths=[
'C:\Program Files (X86)\Microsoft SDKs\Windows',
'C:\Program Files\Microsoft SDKs\Windows'
]
paths.each {|d| pf=d if pf==nil and FileTest.exists?(d) }
if pf!=nil
pf.delete(".")
pf.delete("..")
for d in Dir.entries(pf)
if ![".",".."].include?(d)
pth=pf+"\\"+d+"\\lib"
if FileTest.exists?(pth+"\\sapi.lib")
suc=find_library("SAPI",nil,"\"#{pth.gsub("\\","/")}\"")
break
end
end
end
end
abort "SAPI is missing." if !suc
end
create_makefile 'tolk'
95 changes: 95 additions & 0 deletions src/ruby/tolk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* Product: Tolk
* File: Tolk.cpp
* Description: Ruby C++ Native Extension
* Copyright: (c) 2014-2018, Davy Kager <mail@davykager.nl>
* Ruby Tolk module written by Dawid Pieper <dawidpieper@o2.pl>
* License: LGPLv3
*/

// Ruby Tolk module builds using Tolk code so it is not needed to include 'tolk.dll' library with the project
#ifndef UNICODE
#define _UNICODE
#define UNICODE
#endif
#define _EXPORTING
#include <string>
#include "../fsapi.c"
#include "../wineyes.c"
#include "../zt.c"
#include "../ScreenReaderDriver.h"
#include "../ScreenReaderDriverJAWS.cpp"
#include "../ScreenReaderDriverSA.cpp"
#include "../ScreenReaderDriverSAPI.cpp"
#include "../ScreenReaderDriverSNova.cpp"
#include "../ScreenReaderDriverWE.cpp"
#include "../ScreenReaderDriverZT.cpp"
#include "../java/com_davykager_tolk_Tolk.cpp"
#include <sapi.h>
#include "../ScreenReaderDriverNVDA.cpp"
#include "../tolk.cpp"
#include "rice/Data_Type.hpp"
#include "rice/Constructor.hpp"

using namespace Rice;

// Ruby Rice gem uses std::string to represent Ruby Strings while Tolk uses wchar_t, so it is needed to write some wrapper functions converting Unicoded wchar_t to std::string

BOOL rb_Tolk_Output(std::string str, BOOL interrupt) {
int sz = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring widestr( sz, 0 );
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &widestr[0], sz);
return Tolk_Output(widestr.c_str(), interrupt);
}

BOOL rb_Tolk_Speak(std::string str, BOOL interrupt) {
int sz = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring widestr( sz, 0 );
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &widestr[0], sz);
return Tolk_Speak(widestr.c_str(), interrupt);
}

BOOL rb_Tolk_Braille(std::string str) {
int sz = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring widestr( sz, 0 );
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &widestr[0], sz);
return Tolk_Braille(widestr.c_str());
}

std::string rb_Tolk_DetectScreenReader() {
const wchar_t *t = Tolk_DetectScreenReader();
// Ruby Rice library does not support returning of NULL values in std::string methods
if(t==NULL) {
std::string s("");
return s;
}
std::wstring ws(t);
int sz = WideCharToMultiByte(CP_UTF8, 0, &ws[0], ws.size(), NULL, 0, NULL, NULL);
std::string str(sz, 0);
WideCharToMultiByte(CP_UTF8, 0, &ws[0], (int)ws.size(), &str[0], sz, NULL, NULL);
return str;
}

void rb_tolk_define() {
Module mod = define_module("Tolk");
mod.define_module_function("load", &Tolk_Load);
mod.define_module_function("isLoaded", &Tolk_IsLoaded);
mod.define_module_function("unload", &Tolk_Unload);
mod.define_module_function("trySAPI", &Tolk_TrySAPI);
mod.define_module_function("preferSAPI", &Tolk_PreferSAPI);
mod.define_module_function("detectScreenReader", &rb_Tolk_DetectScreenReader);
mod.define_module_function("hasSpeech", &Tolk_HasSpeech);
mod.define_module_function("hasBraille", &Tolk_HasBraille);
mod.define_module_function("output", &rb_Tolk_Output);
mod.define_module_function("speak", &rb_Tolk_Speak);
mod.define_module_function("braille", &rb_Tolk_Braille);
mod.define_module_function("isSpeaking", &Tolk_IsSpeaking);
mod.define_module_function("silence", &Tolk_Silence);

}

extern "C" {
void Init_tolk(void) {
rb_tolk_define();
}
}