Make wine-access more generic, not specifically cthulhu pathed.

This commit is contained in:
Storm Dragon committed 2026-10-14 16:19:52 -04:00
1 parent 417ee40dda
commit ed8c8e2467
11 files changed
+58 -50

No files matched your search

+10 -10
View File
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20)
project(wine_access LANGUAGES C CXX)
include(GNUInstallDirs)
set(WINE_ACCESS_INSTALL_DIR "${CMAKE_INSTALL_LIBEXECDIR}/cthulhu/wine" CACHE PATH
set(WINE_ACCESS_INSTALL_DIR "${CMAKE_INSTALL_LIBEXECDIR}/wine-access" CACHE PATH
"Installation directory for the Wine helper and its Winelib sidecar")
find_package(PkgConfig REQUIRED)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
@@ -51,14 +51,14 @@ add_custom_command(
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/nvdaController.idl"
VERBATIM)
add_executable(cthulhu-wine-access reader_events.cpp msaa_events.cpp main.cpp foreground_focus.cpp list_view.cpp native_items.cpp review_capture.cpp review_x11.cpp review_service.cpp "${generated_server}")
add_dependencies(cthulhu-wine-access wine-access-menu wine-access-menu32)
target_compile_features(cthulhu-wine-access PRIVATE cxx_std_20)
target_include_directories(cthulhu-wine-access PRIVATE "${generated_dir}")
target_link_libraries(cthulhu-wine-access PRIVATE
add_executable(wine-access reader_events.cpp msaa_events.cpp main.cpp foreground_focus.cpp list_view.cpp native_items.cpp review_capture.cpp review_x11.cpp review_service.cpp "${generated_server}")
add_dependencies(wine-access wine-access-menu wine-access-menu32)
target_compile_features(wine-access PRIVATE cxx_std_20)
target_include_directories(wine-access PRIVATE "${generated_dir}")
target_link_libraries(wine-access PRIVATE
PkgConfig::GIO PkgConfig::XCB oleacc ole32 oleaut32 rpcrt4 user32 gdi32 shell32)
target_link_options(cthulhu-wine-access PRIVATE -mwindows)
target_compile_options(cthulhu-wine-access PRIVATE
target_link_options(wine-access PRIVATE -mwindows)
target_compile_options(wine-access PRIVATE
$<$<COMPILE_LANGUAGE:C,CXX>:-Wall -Wextra>)
include(CTest)
@@ -115,10 +115,10 @@ endif()
# installation looks for the Linux target name, so install both emitted
# artifacts explicitly and keep them together for Wine to resolve.
install(PROGRAMS
"${CMAKE_CURRENT_BINARY_DIR}/cthulhu-wine-access.exe"
"${CMAKE_CURRENT_BINARY_DIR}/wine-access.exe"
DESTINATION "${WINE_ACCESS_INSTALL_DIR}")
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/cthulhu-wine-access.exe.so"
"${CMAKE_CURRENT_BINARY_DIR}/wine-access.exe.so"
"${menu_hook}"
"${menu_hook32}"
"${menu_host32}"
+21 -15
View File
@@ -1,7 +1,7 @@
# Wine Access
`wine-access` is the standalone Wine-hosted accessibility helper for Cthulhu
and readers that implement its Wine D-Bus protocol. An Orca endpoint is
`wine-access` is a standalone Wine-hosted accessibility helper for screen
readers that implement its Wine D-Bus protocol. An Orca endpoint is
available for future Orca-side integration; stock Orca does not implement
the required Wine methods.
@@ -34,8 +34,8 @@ imports remain valid across reader restarts. Close and reopen applications after
updating Wine Access to load the new hooks. `--no-dialog-reader` disables these
hooks along with standard control reading.
The executable is named `cthulhu-wine-access.exe` for compatibility with the
Cthulhu supervisor.
The executable is named `wine-access.exe`. Its launcher, Winelib sidecar,
and native hooks share a reader-independent installation directory.
## Requirements
@@ -60,8 +60,8 @@ provides package-managed installation and upgrades. Choose one installation
method to avoid a local copy taking precedence over the system package.
The convenience script builds in `./build`. Running it as a user installs to
`$HOME/.local/libexec/cthulhu/wine`; running it as root installs system wide to
`/usr/libexec/cthulhu/wine`:
`$HOME/.local/libexec/wine-access`; running it as root installs system wide to
`/usr/libexec/wine-access`:
```sh
./build.sh
@@ -91,20 +91,26 @@ helper directory:
That installs the helper and its Winelib sidecar as:
```text
$prefix/libexec/cthulhu/wine/cthulhu-wine-access.exe
$prefix/libexec/cthulhu/wine/cthulhu-wine-access.exe.so
$prefix/libexec/cthulhu/wine/wine-access-menu.dll
$prefix/libexec/cthulhu/wine/wine-access-menu32.dll
$prefix/libexec/cthulhu/wine/wine-access-menu-host32.exe
$prefix/libexec/wine-access/wine-access.exe
$prefix/libexec/wine-access/wine-access.exe.so
$prefix/libexec/wine-access/wine-access-menu.dll
$prefix/libexec/wine-access/wine-access-menu32.dll
$prefix/libexec/wine-access/wine-access-menu-host32.exe
```
For Cthulhu, either set `CTHULHU_WINE_ACCESS_HELPER` to the installed
executable or place it at:
executable or install it under one of these prefixes:
```text
$HOME/.local/libexec/cthulhu/wine/cthulhu-wine-access.exe
$HOME/.local/libexec/wine-access/wine-access.exe
/usr/local/libexec/wine-access/wine-access.exe
/usr/libexec/wine-access/wine-access.exe
```
Cthulhu checks the environment override first, then the user installation,
`/usr/local`, `/usr`, and finally `PATH`. Its existing Cthulhu-specific user
and system paths remain supported; avoid leaving stale user copies installed.
The helper is started automatically when Cthulhu detects an active Wine
loader for the same user and prefix. It requires the selected reader service
to be running; it exits if that service is unavailable.
@@ -115,7 +121,7 @@ The default invocation and `--reader cthulhu` use the existing Cthulhu endpoint.
An Orca-side integration can launch the helper in the application's Wine prefix:
```sh
WINEPREFIX=/path/to/prefix /path/to/cthulhu-wine-access.exe --reader orca
WINEPREFIX=/path/to/prefix /path/to/wine-access.exe --reader orca
```
| Reader | Session bus name and interface | Object path |
@@ -129,7 +135,7 @@ with `--reader-path` and `--reader-interface`; omitted fields retain the
selected reader's defaults. For an extension class named `WineAccess`:
```sh
WINEPREFIX=/path/to/prefix /path/to/cthulhu-wine-access.exe --reader orca \
WINEPREFIX=/path/to/prefix /path/to/wine-access.exe --reader orca \
--reader-path /org/gnome/Orca1/Service/WineAccess \
--reader-interface org.gnome.Orca1.WineAccess
```
+4 -4
View File
@@ -32,8 +32,8 @@ else
defaultPrefix="${HOME}/.local"
fi
prefix=${2:-"$defaultPrefix"}
installDir="${prefix%/}/libexec/cthulhu/wine"
installedFiles=(cthulhu-wine-access.exe cthulhu-wine-access.exe.so wine-access-menu.dll
installDir="${prefix%/}/libexec/wine-access"
installedFiles=(wine-access.exe wine-access.exe.so wine-access-menu.dll
wine-access-menu32.dll wine-access-menu-host32.exe)
has_installation() {
@@ -53,7 +53,7 @@ if "$removeInstalled"; then
rm -f -- "$installDir/$installedFile"
done
echo "Removed Wine Access from $installDir"
elif (( EUID != 0 && $# < 2 )) && has_installation "$systemPrefix/libexec/cthulhu/wine"; then
elif (( EUID != 0 && $# < 2 )) && has_installation "$systemPrefix/libexec/wine-access"; then
echo "Only a system-wide installation was found. Run: sudo ./build.sh -r" >&2
exit 1
else
@@ -112,6 +112,6 @@ cmake \
-DCMAKE_TOOLCHAIN_FILE="$projectDir/winelib-toolchain.cmake" \
-DCMAKE_INSTALL_PREFIX="$prefix" \
-DCMAKE_INSTALL_LIBEXECDIR:PATH=libexec \
-DWINE_ACCESS_INSTALL_DIR:PATH=libexec/cthulhu/wine
-DWINE_ACCESS_INSTALL_DIR:PATH=libexec/wine-access
cmake --build "$buildDir" --parallel
cmake --install "$buildDir"
@@ -1,8 +1,8 @@
# Maintainer: Storm Dragon <storm_dragon@stormux.org>
pkgname=wine-access-git
pkgver=r35.g95cb78d
pkgver=r37.g417ee40
pkgrel=1
pkgdesc='Wine accessibility helper with MSAA, NVDA Controller, and Tolk compatibility for Cthulhu'
pkgdesc='Wine accessibility helper with MSAA, NVDA Controller, and Tolk compatibility for screen readers'
arch=('x86_64')
url='https://git.stormux.org/storm/wine-access'
license=('LGPL-2.1-or-later')
@@ -40,7 +40,7 @@ package() {
DESTDIR="$pkgdir" cmake --install "$srcdir/build"
# CMake installs these artifacts as files; Wine's launcher must be executable.
chmod 755 "$pkgdir/usr/libexec/cthulhu/wine/cthulhu-wine-access.exe"
chmod 755 "$pkgdir/usr/libexec/wine-access/wine-access.exe"
install -Dm644 "$srcdir/wine-access/README.md" \
"$pkgdir/usr/share/doc/wine-access/README.md"
}
@@ -13,7 +13,7 @@ Before the remote exists, build from the committed sources in your local
checkout instead:
```sh
WINE_ACCESS_GIT_URL=file:///home/storm/git/wine-access makepkg -si
WINE_ACCESS_GIT_URL=file:///path/to/wine-access makepkg -si
```
Git sources include committed files only. Adjust that path if your checkout is
@@ -25,21 +25,23 @@ WINE_ACCESS_GIT_URL=https://git.stormux.org/storm/wine-access.git makepkg -si
The package installs the Winelib launcher, its sidecar, both native menu hook
DLLs, and the 32-bit menu host
under `/usr/libexec/cthulhu/wine/`. It provides and conflicts with the older
`cthulhu-wine-access` helper, including `cthulhu-wine-access-git`, so pacman
under `/usr/libexec/wine-access/`. It provides and conflicts with the older
`cthulhu-wine-access` helper, so pacman
can replace that package in the installation transaction.
Use this package for subsequent updates rather than also installing through
`build.sh`. If an earlier local installation exists under
`~/.local/libexec/cthulhu/wine`, remove it with `./build.sh -r` from the project
root before using the package: readers may prefer that local copy. Do not
`~/.local/libexec/wine-access`, remove it with `./build.sh -r` from the project
root before using the package: readers may prefer that local copy. For the older
`~/.local/libexec/cthulhu/wine` layout, use the old version of `build.sh -r`. Do not
remove package-owned system files with `build.sh -r`.
If your reader does not discover the system
location automatically, set this in the environment of the reader's service:
```sh
export CTHULHU_WINE_ACCESS_HELPER=/usr/libexec/cthulhu/wine/cthulhu-wine-access.exe
export CTHULHU_WINE_ACCESS_HELPER=/usr/libexec/wine-access/wine-access.exe
```
The helper requires a running reader implementing the Cthulhu D-Bus service.
The helper requires a running reader implementing its Wine D-Bus protocol;
see the project README for reader selection and endpoint overrides.
+2 -2
View File
@@ -83,7 +83,7 @@ with tempfile.TemporaryDirectory(prefix="wine-access-controller-") as temporary:
str(source / "tests/controller_fixture.c"), "-lrpcrt4"], check=True)
helper = None
client = None
helperCommand = [str(build / "cthulhu-wine-access.exe"), "--no-dialog-reader",
helperCommand = [str(build / "wine-access.exe"), "--no-dialog-reader",
*endpointArguments,
*(["--reader", args.reader] if args.reader else [])]
try:
@@ -98,7 +98,7 @@ with tempfile.TemporaryDirectory(prefix="wine-access-controller-") as temporary:
["--reader-interface"], ["--reader-interface", ""],
["--reader-interface", "WineAccess"],
["--reader-interface", "org.example.Bad-Interface"]):
result = subprocess.run([str(build / "cthulhu-wine-access.exe"), *readerArgs],
result = subprocess.run([str(build / "wine-access.exe"), *readerArgs],
env=env, timeout=5)
assert result.returncode == 1, "invalid endpoint argument was accepted"
assert name_call("RequestName", busName) == 1
+1 -1
View File
@@ -78,7 +78,7 @@ with tempfile.TemporaryDirectory(prefix="wine-event-stall-") as temporary:
children = []
try:
subprocess.run(["wineboot", "-u"], env=env, check=True, timeout=45)
helper = subprocess.Popen([str(build / "cthulhu-wine-access.exe"), "--no-controller",
helper = subprocess.Popen([str(build / "wine-access.exe"), "--no-controller",
"--reader", args.reader], env=env)
children.append(helper)
time.sleep(1)
+3 -3
View File
@@ -115,7 +115,7 @@ with tempfile.TemporaryDirectory(prefix="wine-access-menus-") as temporary:
while not ready.exists() and app.poll() is None and time.monotonic() < deadline:
time.sleep(0.01)
assert ready.exists(), "editor did not become ready before helper attachment"
helper = subprocess.Popen([str(build / "cthulhu-wine-access.exe"), "--no-controller", *readerArguments], env=env)
helper = subprocess.Popen([str(build / "wine-access.exe"), "--no-controller", *readerArguments], env=env)
# Allow the helper to register its bridge before opening the fixture.
deadline = time.monotonic() + 1
while time.monotonic() < deadline:
@@ -133,7 +133,7 @@ with tempfile.TemporaryDirectory(prefix="wine-access-menus-") as temporary:
if args.restart_helper and not restarted and any(e[0].endswith(":text") for e in events):
helper.terminate()
helper.wait(timeout=5)
helper = subprocess.Popen([str(build / "cthulhu-wine-access.exe"), "--no-controller", *readerArguments], env=env)
helper = subprocess.Popen([str(build / "wine-access.exe"), "--no-controller", *readerArguments], env=env)
restarted = True
time.sleep(0.01)
assert app.poll() == 0, "fixture failed or timed out"
@@ -337,7 +337,7 @@ with tempfile.TemporaryDirectory(prefix="wine-access-menus-") as temporary:
assert any(e[2] == "Return to control" and e[3] == "button" for e in events), "control focus missing"
assert any(e[2] == "Application-owned accessibility" and e[3] == "client"
for e in events), "marshaled application MSAA object unavailable"
subprocess.run([str(build / "cthulhu-wine-access.exe"),
subprocess.run([str(build / "wine-access.exe"),
"--no-dialog-reader", "--no-controller"],
env=env, check=True, timeout=5)
print("PASS: native and nested menus, context menus, shortcuts, states, "
+1 -1
View File
@@ -67,7 +67,7 @@ with tempfile.TemporaryDirectory(prefix="wine-access-notifications-") as tempora
helper = app = None
try:
subprocess.run(["wineboot", "-u"], env=env, check=True, timeout=45)
helper = subprocess.Popen([str(build / "cthulhu-wine-access.exe"), "--no-controller",
helper = subprocess.Popen([str(build / "wine-access.exe"), "--no-controller",
"--reader", args.reader], env=env)
time.sleep(.5)
app = subprocess.Popen(["wine", str(fixture),
+1 -1
View File
@@ -83,7 +83,7 @@ with tempfile.TemporaryDirectory(prefix="wine-reader-stall-") as temporary:
children = []
try:
subprocess.run(["wineboot", "-u"], env=env, check=True, timeout=45)
helper = subprocess.Popen([str(build / "cthulhu-wine-access.exe"), "--no-controller"], env=env)
helper = subprocess.Popen([str(build / "wine-access.exe"), "--no-controller"], env=env)
children.append(helper)
time.sleep(1)
app = subprocess.Popen(["wine", str(fixture)], env=env)
+3 -3
View File
@@ -94,7 +94,7 @@ with tempfile.TemporaryDirectory(prefix='wine-review-wire-') as temporary:
return result[0]
try:
subprocess.run(['wineboot','-u'],env=env,check=True,timeout=45)
helper = subprocess.Popen([str(build/'cthulhu-wine-access.exe'),'--no-controller',*readerArguments],env=env)
helper = subprocess.Popen([str(build/'wine-access.exe'),'--no-controller',*readerArguments],env=env)
app = subprocess.Popen(['wine',str(fixture)],env=env)
pump_until(lambda: any(f[4]=='Wine review fixture' for f in focuses.values()),8)
reply, elapsed = capture()
@@ -187,7 +187,7 @@ with tempfile.TemporaryDirectory(prefix='wine-review-wire-') as temporary:
helper.terminate(); helper.wait(timeout=3)
subprocess.run(['wine',str(fixture),'--check-remote'],env=env,check=True,timeout=5)
print('PASS: test_native_buffer_lifetime_after_helper_stop')
helper=subprocess.Popen([str(build/'cthulhu-wine-access.exe'),'--no-controller',*readerArguments],env=env)
helper=subprocess.Popen([str(build/'wine-access.exe'),'--no-controller',*readerArguments],env=env)
pump_until(lambda:any(s != sender and f[4]=='Wine review fixture' for s,f in focuses.items()),5)
focuses.pop(sender,None)
configure(7)
@@ -215,7 +215,7 @@ with tempfile.TemporaryDirectory(prefix='wine-review-wire-') as temporary:
connection.unregister_object(registration)
registration = connection.register_object(path,Gio.DBusNodeInfo.new_for_xml(interface_xml(False)).interfaces[0],record,None,None)
events.clear()
helper = subprocess.Popen([str(build/'cthulhu-wine-access.exe'),'--no-controller',*readerArguments],env=env)
helper = subprocess.Popen([str(build/'wine-access.exe'),'--no-controller',*readerArguments],env=env)
end=time.monotonic()+1
while time.monotonic()<end:
while GLib.MainContext.default().iteration(False): pass