44# Copyright (C) 2021 NV Access Limited
55
66from dataclasses import dataclass
7- from typing import List , Optional
7+ from typing import List
88import enum
99import braille
1010import inputCore
@@ -90,7 +90,8 @@ def registerAutomaticDetection(cls, driverRegistrar: DriverRegistrar):
9090
9191 def __init__ (self , port = "auto" ):
9292 super ().__init__ ()
93- self .numCells = 0
93+ self .numRows = 1
94+ self .numCols = 0
9495
9596 for portType , portId , port , portInfo in self ._getTryPorts (port ):
9697 if portType != bdDetect .DeviceType .HID :
@@ -103,16 +104,27 @@ def __init__(self, port="auto"):
103104 continue # Couldn't connect.
104105 if self ._dev .usagePage != HID_USAGE_PAGE_BRAILLE :
105106 log .debug ("Not braille" )
107+ self ._dev .close ()
106108 continue
107109 cellValueCaps = self ._findCellValueCaps ()
108- if cellValueCaps :
110+ if len (cellValueCaps ) > 0 :
111+ if any (x .ReportCount != cellValueCaps [0 ].ReportCount for x in cellValueCaps ):
112+ log .warning ("Found multi-line display with an irregular shape, ignoring." )
113+ self ._dev .close ()
114+ continue
115+ self .numRows = len (cellValueCaps )
116+ self .numCols = cellValueCaps [0 ].ReportCount
117+ self ._maxNumberOfCells = self .numCells
109118 self ._cellValueCaps = cellValueCaps
110- self ._numberOfCellsValueCaps = self ._findNumberOfCellsValueCaps ()
111- self .numCells = self ._maxNumberOfCells = cellValueCaps .ReportCount
119+ if self .numRows == 1 :
120+ self ._numberOfCellsValueCaps = self ._findNumberOfCellsValueCaps ()
121+ elif self ._findNumberOfCellsValueCaps ():
122+ log .warning ("The number of braille cells usage is not supported on multi-line displays" )
112123 # A display responded.
113124 log .info (
114- "Found display with {cells} cells connected via {type} ({port})" .format (
115- cells = self .numCells ,
125+ "Found display with {rows} rows, {cols} cols connected via {type} ({port})" .format (
126+ rows = self .numRows ,
127+ cols = self .numCols ,
116128 type = portType ,
117129 port = port ,
118130 ),
@@ -126,8 +138,10 @@ def __init__(self, port="auto"):
126138 self ._keysDown = set ()
127139 self ._ignoreKeyReleases = False
128140
129- def _findCellValueCaps (self ) -> Optional [hidpi .HIDP_VALUE_CAPS ]:
130- for valueCaps in self ._dev .outputValueCaps :
141+ def _findCellValueCaps (self ) -> list [hidpi .HIDP_VALUE_CAPS ]:
142+ return [
143+ valueCaps
144+ for valueCaps in self ._dev .outputValueCaps
131145 if (
132146 valueCaps .LinkUsagePage == HID_USAGE_PAGE_BRAILLE
133147 and valueCaps .LinkUsage == BraillePageUsageID .BRAILLE_ROW
@@ -137,9 +151,8 @@ def _findCellValueCaps(self) -> Optional[hidpi.HIDP_VALUE_CAPS]:
137151 BraillePageUsageID .SIX_DOT_BRAILLE_CELL ,
138152 )
139153 and valueCaps .ReportCount > 0
140- ):
141- return valueCaps
142- return None
154+ )
155+ ]
143156
144157 def _findNumberOfCellsValueCaps (self ) -> hidpi .HIDP_VALUE_CAPS | None :
145158 for valueCaps in self ._dev .inputValueCaps :
@@ -226,13 +239,20 @@ def display(self, cells: List[int]):
226239 # cells will already be padded up to numCells.
227240 padded_cells = cells + [0 ] * (self ._maxNumberOfCells - len (cells ))
228241 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- )
242+ reportID = self ._cellValueCaps [0 ].ReportID
243+ report = hwIo .hid .HidOutputReport (self ._dev , reportID = reportID )
244+ for valueCap in self ._cellValueCaps :
245+ if valueCap .ReportID != reportID :
246+ self ._dev .write (report .data )
247+ reportID = valueCap .ReportID
248+ report = hwIo .hid .HidOutputReport (self ._dev , reportID = reportID )
249+ report .setUsageValueArray (
250+ HID_USAGE_PAGE_BRAILLE ,
251+ valueCap .LinkCollection ,
252+ valueCap .u1 .NotRange .Usage ,
253+ cellBytes [:valueCap .ReportCount ],
254+ )
255+ cellBytes = cellBytes [valueCap .ReportCount :]
236256 self ._dev .write (report .data )
237257
238258 gestureMap = inputCore .GlobalGestureMap (
0 commit comments