Skip to content

Commit 175d82b

Browse files
authored
Merge 54a7877 into 2325979
2 parents 2325979 + 54a7877 commit 175d82b

37 files changed

+1234
-215
lines changed

nvdaHelper/archBuild_sconscript

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# This file may be used under the terms of the GNU General Public License, version 2 or later.
44
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html
55

6+
import sysconfig
67

78
Import(
89
"env",
@@ -13,6 +14,7 @@ Import(
1314
)
1415

1516

17+
1618
# some utilities for COM proxies
1719
def clsidStringToCLSIDDefine(clsidString):
1820
"""
@@ -70,7 +72,17 @@ env.AddMethod(COMProxyDllBuilder, "COMProxyDll")
7072
if not env.get("MSVC_VERSION") or tuple(map(int, env.get("MSVC_VERSION").split("."))) < (14, 2):
7173
raise RuntimeError("Visual C++ 14.2 (Visual Studio 2019) or newer not found")
7274

75+
PYTHON_PLATFORM = sysconfig.get_platform()
7376
TARGET_ARCH = env["TARGET_ARCH"]
77+
78+
79+
isNVDACoreArch = (
80+
(PYTHON_PLATFORM == "win32" and TARGET_ARCH == "x86")
81+
or (PYTHON_PLATFORM == "win-amd64" and TARGET_ARCH == "x86_64")
82+
or (PYTHON_PLATFORM == "win-arm64" and TARGET_ARCH == "arm64")
83+
)
84+
85+
7486
debug = env["nvdaHelperDebugFlags"]
7587
release = env["release"]
7688
signExec = env["signExec"] if (bool(env["certFile"]) ^ bool(env["apiSigningToken"])) else None
@@ -174,26 +186,26 @@ Export("env")
174186

175187
acrobatAccessRPCStubs = env.SConscript("acrobatAccess_sconscript")
176188
Export("acrobatAccessRPCStubs")
177-
if TARGET_ARCH == "x86":
189+
if isNVDACoreArch:
178190
env.Install(sourceTypelibDir, acrobatAccessRPCStubs[0]) # typelib
179191

180192
ia2RPCStubs = env.SConscript("ia2_sconscript")
181193
Export("ia2RPCStubs")
182194
if signExec:
183195
env.AddPostAction(ia2RPCStubs[0], [signExec])
184196
env.Install(libInstallDir, ia2RPCStubs[0]) # proxy dll
185-
if TARGET_ARCH == "x86":
197+
if isNVDACoreArch:
186198
env.Install(sourceTypelibDir, ia2RPCStubs[1]) # typelib
187199

188200
iSimpleDomRPCStubs = env.SConscript("ISimpleDOM_sconscript")
189201
if signExec:
190202
env.AddPostAction(iSimpleDomRPCStubs[0], [signExec])
191203
env.Install(libInstallDir, iSimpleDomRPCStubs[0]) # proxy dll
192-
if TARGET_ARCH == "x86":
204+
if isNVDACoreArch:
193205
env.Install(sourceTypelibDir, iSimpleDomRPCStubs[1]) # typelib
194206

195207
mathPlayerRPCStubs = env.SConscript("mathPlayer_sconscript")
196-
if TARGET_ARCH == "x86":
208+
if isNVDACoreArch:
197209
env.Install(sourceTypelibDir, mathPlayerRPCStubs[0]) # typelib
198210

199211
detoursLib = env.SConscript("detours/sconscript")
@@ -202,7 +214,7 @@ Export("detoursLib")
202214
apiHookObj = env.Object("apiHook", "common/apiHook.cpp")
203215
Export("apiHookObj")
204216

205-
if TARGET_ARCH == "x86":
217+
if isNVDACoreArch:
206218
localLib = env.SConscript("local/sconscript")
207219
Export("localLib")
208220
if signExec:
@@ -231,12 +243,11 @@ if signExec:
231243
env.AddPostAction(remoteLib[0], [signExec])
232244
env.Install(libInstallDir, remoteLib)
233245

234-
if TARGET_ARCH in ("x86_64", "arm64"):
235-
remoteLoaderProgram = env.SConscript("remoteLoader/sconscript")
236-
if signExec:
237-
env.AddPostAction(remoteLoaderProgram, [signExec])
238-
env.Install(libInstallDir, remoteLoaderProgram)
246+
remoteLoaderProgram = env.SConscript("remoteLoader/sconscript")
247+
if signExec:
248+
env.AddPostAction(remoteLoaderProgram, [signExec])
249+
env.Install(libInstallDir, remoteLoaderProgram)
239250

240-
if TARGET_ARCH == "x86":
251+
if isNVDACoreArch:
241252
thirdPartyEnv.SConscript("espeak/sconscript")
242253
thirdPartyEnv.SConscript("liblouis/sconscript")

nvdaHelper/espeak/sconscript

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# See the file COPYING for more details.
44
# Copyright (C) 2011-2025 NV Access Limited
55

6+
import ctypes.wintypes
67
import enum
78
import typing
89
import os
@@ -22,10 +23,12 @@ Import(
2223
]
2324
)
2425

26+
freeLibrary = ctypes.windll.kernel32.FreeLibrary
27+
freeLibrary.argtypes = (ctypes.wintypes.HANDLE,)
2528

2629
class AutoFreeCDLL(ctypes.CDLL):
2730
def __del__(self):
28-
ctypes.windll.kernel32.FreeLibrary(self._handle)
31+
freeLibrary(self._handle)
2932

3033

3134
synthDriversDir = sourceDir.Dir("synthDrivers")

nvdaHelper/liblouis/sconscript

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ env.Append(M4FLAGS="-G")
6767
if "analyze" in env["nvdaHelperDebugFlags"]:
6868
env.Append(CCFLAGS="/analyze-")
6969

70+
if env["TARGET_ARCH"] in ("x86_64", "arm64"):
71+
# We need to build as 64-bit
72+
env.Append(CCFLAGS="-m64")
73+
7074
env.Append(
7175
CPPDEFINES=[
7276
# The Visual C++ C Runtime deprecates standard POSIX APIs that conflict with

nvdaHelper/local/nvdaHelperLocal.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ EXPORTS
6969
audioDucking_shouldDelay
7070
logMessage
7171
getOleClipboardText
72+
getOleUserType
7273
_nvdaControllerInternal_reportLiveRegion
7374
_nvdaControllerInternal_openConfigDirectory
7475
rateLimitedUIAEventHandler_create

nvdaHelper/local/oleUtils.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This license can be found at:
1414

1515
#include <windows.h>
1616
#include <wtypes.h>
17+
#include <atlcomcli.h>
1718
#include <common/log.h>
1819

1920
/*
@@ -22,10 +23,19 @@ This license can be found at:
2223
* @param text a pointer to a BSTR which will hold the resulting text
2324
* @return S_OK on success or an OLE error code.
2425
*/
25-
HRESULT getOleClipboardText(IDataObject* dataObject, BSTR* text) {
26+
HRESULT getOleClipboardText(IUnknown* pUnknown, BSTR* text) {
27+
if (!pUnknown) {
28+
LOG_DEBUGWARNING(L"pUnknown is null.");
29+
return E_INVALIDARG;
30+
}
31+
CComQIPtr<IDataObject> pDataObject(pUnknown);
32+
if (!pDataObject) {
33+
LOG_DEBUGWARNING(L"Could not get IDataObject interface from pUnknown");
34+
return E_NOINTERFACE;
35+
}
2636
FORMATETC format={CF_UNICODETEXT,nullptr,DVASPECT_CONTENT,-1,TYMED_HGLOBAL};
2737
STGMEDIUM medium={0};
28-
HRESULT res=dataObject->GetData(&format,&medium);
38+
HRESULT res=pDataObject->GetData(&format,&medium);
2939
if(FAILED(res)) {
3040
LOG_DEBUGWARNING(L"IDataObject::getData failed with error "<<res);
3141
return res;
@@ -42,3 +52,38 @@ HRESULT getOleClipboardText(IDataObject* dataObject, BSTR* text) {
4252
ReleaseStgMedium(&medium);
4353
return res;
4454
}
55+
56+
HRESULT getOleUserType(IUnknown* pUnknown, DWORD dwFlags, BSTR* userType) {
57+
if (!pUnknown) {
58+
LOG_DEBUGWARNING(L"pUnknown is null.");
59+
return E_INVALIDARG;
60+
}
61+
if(!userType) {
62+
LOG_DEBUGWARNING(L"userType is null.");
63+
return E_INVALIDARG;
64+
}
65+
CComQIPtr<IOleObject> pOleObject(pUnknown);
66+
if (!pOleObject) {
67+
LOG_DEBUGWARNING(L"Could not get IOleObject interface from pUnknown");
68+
return E_NOINTERFACE;
69+
}
70+
LPOLESTR pOleStr{nullptr};
71+
HRESULT res = pOleObject->GetUserType(dwFlags, &pOleStr);
72+
if (FAILED(res)) {
73+
LOG_DEBUGWARNING(L"IOleObject::GetUserType failed with error " << res
74+
<< L" for flags " << dwFlags);
75+
return res;
76+
}
77+
if (!pOleStr) {
78+
LOG_DEBUGWARNING(L"IOleObject::GetUserType returned null string for flags " << dwFlags);
79+
return E_FAIL;
80+
}
81+
*userType = SysAllocString(pOleStr);
82+
CComPtr<IMalloc> pMalloc;
83+
if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pMalloc)) && pMalloc) {
84+
pMalloc->Free(pOleStr);
85+
} else {
86+
LOG_ERROR(L"Failed to get IMalloc interface to free memory for pOleStr");
87+
}
88+
return S_OK;
89+
}

nvdaHelper/local/wasapi.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ HRESULT WasapiPlayer::feed(unsigned char* data, unsigned int size,
361361
} else {
362362
// Silence ends in this chunk. Skip the silence and continue.
363363
data += silenceSize;
364-
size -= silenceSize;
364+
size -= (unsigned int)silenceSize;
365365
remainingFrames = size / format.nBlockAlign;
366366
isTrimmingLeadingSilence = false; // Stop checking for silence
367367

@@ -780,12 +780,12 @@ void SilencePlayer::generateWhiteNoise(float volume) {
780780
if (volume == 0) {
781781
return;
782782
}
783-
UINT32 n = whiteNoiseData.size();
783+
size_t n = whiteNoiseData.size();
784784
const double mean = 0.0;
785785
const double stddev = volume * 256;
786786
std::default_random_engine generator;
787787
std::normal_distribution<double> dist(mean, stddev);
788-
for (UINT32 i = 0; i < n; i++) {
788+
for (size_t i = 0; i < n; i++) {
789789
whiteNoiseData[i] = (INT16)dist(generator);
790790
}
791791
}

projectDocs/dev/buildingNVDA.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,22 @@ scons launcher version=test1
114114
```
115115

116116
For more see the [sconstruct file](../../sconstruct).
117+
118+
## Creating experimental 64-bit builds
119+
120+
To use NVDA's experimental 64-bit support, instruct UV to use a 64-bit version of python.
121+
122+
```ps
123+
$env:UV_PYTHON="cpython-3.11.9-windows-x86_64-none"
124+
```
125+
126+
or
127+
128+
```cmd
129+
set UV_PYTHON=cpython-3.11.9-windows-x86_64-none
130+
```
131+
132+
* This will apply to all projects managed by UV.
133+
* This will not persist across terminal sessions.
134+
135+
If you're using Visual Studio Code as your IDE, our [workspace configuration](https://github.com/nvaccess/vscode-nvda/) includes [terminal profiles](https://code.visualstudio.com/docs/terminal/profiles) to set these environment variables for you in PowerShell or Command Prompt.

sconstruct

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import multiprocessing
99
import os
10+
import platform
1011
import sys
1112
from pathlib import Path
1213

@@ -104,6 +105,20 @@ vars.Add(
104105
allowed_values=[str(x) for x in range(60)],
105106
)
106107
)
108+
vars.Add(
109+
EnumVariable(
110+
'targetArch',
111+
help="Target architecture of the build output",
112+
default='x86',
113+
allowed_values=('x86', 'x86_64'),
114+
map={
115+
'32bit': 'x86',
116+
'64bit': 'x86_64',
117+
'x64': 'x86_64',
118+
},
119+
ignorecase=2 # Always downcase,
120+
)
121+
)
107122

108123
# Base environment for this and sub sconscripts
109124
env = Environment(
@@ -118,6 +133,7 @@ env = Environment(
118133
],
119134
)
120135

136+
121137
# speed up subsequent runs by checking timestamps of targets and dependencies, and only using md5 if timestamps differ.
122138
env.Decider("MD5-timestamp")
123139

@@ -172,13 +188,13 @@ sourceDir = env.Dir("source")
172188
Export("sourceDir")
173189
clientDir = Dir("extras/controllerClient")
174190
Export("clientDir")
175-
sourceLibDir = sourceDir.Dir("lib")
191+
sourceLibDir = sourceDir.Dir("lib/x86")
176192
Export("sourceLibDir")
177193
sourceTypelibDir = sourceDir.Dir("typelibs")
178194
Export("sourceTypelibDir")
179-
sourceLibDir64 = sourceDir.Dir("lib64")
195+
sourceLibDir64 = sourceDir.Dir("lib/x64")
180196
Export("sourceLibDir64")
181-
sourceLibDirArm64 = sourceDir.Dir("libArm64")
197+
sourceLibDirArm64 = sourceDir.Dir("lib/arm64")
182198
Export("sourceLibDirArm64")
183199
buildDir = Dir("build")
184200
outFilePrefix = "nvda{type}_{version}".format(type="" if release else "_snapshot", version=version)
@@ -236,7 +252,10 @@ env32["STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME"] = 1
236252
env64["STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME"] = 1
237253
envArm64["STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME"] = 1
238254

239-
env = env32
255+
if platform.architecture()[0].startswith("64"):
256+
env = env64
257+
else:
258+
env = env32
240259

241260
projectRCSubstDict = {
242261
"%version_year%": env["version_year"],

source/JABHandler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ def initialize():
11371137
global bridgeDll, isRunning
11381138
try:
11391139
bridgeDll = cdll.LoadLibrary(
1140-
os.path.join(NVDAHelper.versionedLibPath, "windowsaccessbridge-32.dll"),
1140+
os.path.join(NVDAHelper.versionedLibX86Path, "windowsaccessbridge-32.dll"),
11411141
)
11421142
except WindowsError:
11431143
raise NotImplementedError("dll not available")

0 commit comments

Comments
 (0)