Skip to content

Commit 94f064c

Browse files
authored
Merge f692a23 into fa442e5
2 parents fa442e5 + f692a23 commit 94f064c

2 files changed

Lines changed: 43 additions & 20 deletions

File tree

source/brailleDisplayDrivers/hidBrailleStandard.py

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
# Copyright (C) 2021 NV Access Limited
55

66
from dataclasses import dataclass
7-
from typing import List, Optional
7+
from typing import List
88
import enum
9+
import itertools
910
import braille
1011
import inputCore
1112
from logHandler import log
@@ -90,7 +91,8 @@ def registerAutomaticDetection(cls, driverRegistrar: DriverRegistrar):
9091

9192
def __init__(self, port="auto"):
9293
super().__init__()
93-
self.numCells = 0
94+
self.numRows = 1
95+
self.numCols = 0
9496

9597
for portType, portId, port, portInfo in self._getTryPorts(port):
9698
if portType != bdDetect.DeviceType.HID:
@@ -103,16 +105,27 @@ def __init__(self, port="auto"):
103105
continue # Couldn't connect.
104106
if self._dev.usagePage != HID_USAGE_PAGE_BRAILLE:
105107
log.debug("Not braille")
108+
self._dev.close()
106109
continue
107110
cellValueCaps = self._findCellValueCaps()
108-
if cellValueCaps:
111+
if len(cellValueCaps) > 0:
112+
if any(x.ReportCount != cellValueCaps[0].ReportCount for x in cellValueCaps):
113+
log.warning("Found multi-line display with an irregular shape, ignoring.")
114+
self._dev.close()
115+
continue
116+
self.numRows = len(cellValueCaps)
117+
self.numCols = cellValueCaps[0].ReportCount
118+
self._maxNumberOfCells = self.numCells
109119
self._cellValueCaps = cellValueCaps
110-
self._numberOfCellsValueCaps = self._findNumberOfCellsValueCaps()
111-
self.numCells = self._maxNumberOfCells = cellValueCaps.ReportCount
120+
if self.numRows == 1:
121+
self._numberOfCellsValueCaps = self._findNumberOfCellsValueCaps()
122+
elif self._findNumberOfCellsValueCaps():
123+
log.warning("Reserved braille cells are not supported on multi-line displays")
112124
# A display responded.
113125
log.info(
114-
"Found display with {cells} cells connected via {type} ({port})".format(
115-
cells=self.numCells,
126+
"Found display with {rows} rows, {cols} cols connected via {type} ({port})".format(
127+
rows=self.numRows,
128+
cols=self.numCols,
116129
type=portType,
117130
port=port,
118131
),
@@ -126,8 +139,10 @@ def __init__(self, port="auto"):
126139
self._keysDown = set()
127140
self._ignoreKeyReleases = False
128141

129-
def _findCellValueCaps(self) -> Optional[hidpi.HIDP_VALUE_CAPS]:
130-
for valueCaps in self._dev.outputValueCaps:
142+
def _findCellValueCaps(self) -> list[hidpi.HIDP_VALUE_CAPS]:
143+
return [
144+
valueCaps
145+
for valueCaps in self._dev.outputValueCaps
131146
if (
132147
valueCaps.LinkUsagePage == HID_USAGE_PAGE_BRAILLE
133148
and valueCaps.LinkUsage == BraillePageUsageID.BRAILLE_ROW
@@ -137,9 +152,8 @@ def _findCellValueCaps(self) -> Optional[hidpi.HIDP_VALUE_CAPS]:
137152
BraillePageUsageID.SIX_DOT_BRAILLE_CELL,
138153
)
139154
and valueCaps.ReportCount > 0
140-
):
141-
return valueCaps
142-
return None
155+
)
156+
]
143157

144158
def _findNumberOfCellsValueCaps(self) -> hidpi.HIDP_VALUE_CAPS | None:
145159
for valueCaps in self._dev.inputValueCaps:
@@ -226,14 +240,22 @@ def display(self, cells: List[int]):
226240
# cells will already be padded up to numCells.
227241
padded_cells = cells + [0] * (self._maxNumberOfCells - len(cells))
228242
cellBytes = b"".join(intToByte(cell) for cell in padded_cells)
229-
report = hwIo.hid.HidOutputReport(self._dev, reportID=self._cellValueCaps.ReportID)
230-
report.setUsageValueArray(
231-
HID_USAGE_PAGE_BRAILLE,
232-
self._cellValueCaps.LinkCollection,
233-
self._cellValueCaps.u1.NotRange.Usage,
234-
cellBytes,
235-
)
236-
self._dev.write(report.data)
243+
# Iterate through the output reports
244+
for reportID, valueCaps in itertools.groupby(self._cellValueCaps, lambda x: x.ReportID):
245+
report = hwIo.hid.HidOutputReport(self._dev, reportID=reportID)
246+
# Iterate through each row in this report
247+
for valueCap in valueCaps:
248+
# Take the cells for this row from the front of the cellBytes list
249+
rowCellBytes = cellBytes[: valueCap.ReportCount]
250+
cellBytes = cellBytes[valueCap.ReportCount :]
251+
252+
report.setUsageValueArray(
253+
HID_USAGE_PAGE_BRAILLE,
254+
valueCap.LinkCollection,
255+
valueCap.u1.NotRange.Usage,
256+
rowCellBytes,
257+
)
258+
self._dev.write(report.data)
237259

238260
gestureMap = inputCore.GlobalGestureMap(
239261
{

user_docs/en/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ The available options are:
2323
* The `-c`/`--config-path` and `--disable-addons` command line options are now respected when launching an update from within NVDA. (#16937)
2424
* eSpeak NG has been updated to 1.52-dev commit `961454ff`. (#16775)
2525
* Added new languages Faroese and Xextan.
26+
* When using a multi-line braille display via the standard HID braille driver, all lines of cells will be used. (#16993, @alexmoon)
2627

2728
### Bug Fixes
2829

0 commit comments

Comments
 (0)