Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter for the correct usage page in the Brailliant driver #17522

Open
wants to merge 6 commits into
base: rc
Choose a base branch
from
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
4 changes: 4 additions & 0 deletions source/brailleDisplayDrivers/brailliantB.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
HR_KEYS = b"\x04"
HR_BRAILLE = b"\x05"
HR_POWEROFF = b"\x07"
HID_USAGE_PAGE = 0x93

KEY_NAMES = {
1: "power", # Brailliant BI 32, 40 and 80.
Expand Down Expand Up @@ -147,6 +148,9 @@ def __init__(self, port="auto"):
# Try talking to the display.
try:
if self.isHid:
if (usasePage := portInfo.get("HIDUsagePage")) != HID_USAGE_PAGE:
log.debugWarning(f"Ignoring device {port!r} with usage page {usasePage!r}")
continue
self._dev = hwIo.Hid(port, onReceive=self._hidOnReceive)
else:
self._dev = hwIo.Serial(
Expand Down
41 changes: 28 additions & 13 deletions source/hwPortUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import hidpi
import winKernel
from logHandler import log
from winAPI.constants import SystemErrorCodes
from winKernel import SYSTEMTIME


Expand Down Expand Up @@ -496,7 +497,10 @@ def __init__(self, **kwargs):
super().__init__(Size=ctypes.sizeof(HIDD_ATTRIBUTES), **kwargs)


def _getHidInfo(hwId, path):
_getHidInfoCache: dict[str, dict] = {}


def _getHidInfo(hwId: str, path: str) -> dict[str, typing.Any]:
info = {
"hardwareID": hwId,
"devicePath": path,
Expand All @@ -517,18 +521,28 @@ def _getHidInfo(hwId, path):
# Fetch additional info about the HID device.
from serial.win32 import FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE, CreateFile

handle = CreateFile(
path,
0,
winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE,
None,
winKernel.OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
None,
)
if handle == INVALID_HANDLE_VALUE:
if _isDebug():
log.debugWarning(f"Opening device {path} to get additional info failed: {ctypes.WinError()}")
if (
handle := CreateFile(
path,
0,
winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE,
None,
winKernel.OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
None,
)
) == INVALID_HANDLE_VALUE:
if (err := ctypes.GetLastError()) == SystemErrorCodes.SHARING_VIOLATION:
if _isDebug():
log.debugWarning(
f"Opening device {path} to get additional info failed because the device is being used. "
"Falling back to cache for device info",
)
if cachedInfo := _getHidInfoCache.get(path):
cachedInfo.update(info)
return cachedInfo
elif _isDebug():
log.debugWarning(f"Opening device {path} to get additional info failed: {ctypes.WinError(err)}")
return info
try:
attribs = HIDD_ATTRIBUTES()
Expand All @@ -555,6 +569,7 @@ def _getHidInfo(hwId, path):
ctypes.windll.hid.HidD_FreePreparsedData(pd)
finally:
winKernel.closeHandle(handle)
_getHidInfoCache[path] = info
return info


Expand Down
2 changes: 2 additions & 0 deletions source/winAPI/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class SystemErrorCodes(enum.IntEnum):
ACCESS_DENIED = 0x5
INVALID_DATA = 0xD
NOT_READY = 0x15
SHARING_VIOLATION = 0x20
"""The process cannot access the file because it is being used by another process."""
INVALID_PARAMETER = 0x57
MOD_NOT_FOUND = 0x7E
CANCELLED = 0x4C7
3 changes: 3 additions & 0 deletions user_docs/en/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

### Bug Fixes

* When the Standard HID Braille Display driver is explicitly selected as the braille display driver, and the braille display list is opened, NVDA correctly identifies the HID driver as the selected driver instead of showing no driver selected. (#17522, @LeonarddeR)
* The Humanware Brailliant driver is now more reliable in selecting the right connection endpoint, resulting in better connection stability and less errors. (#17522, @LeonarddeR)

## 2024.4.1

This is a patch release to fix a bug when saving speech symbol dictionaries.
Expand Down