Repository: nvaccess/nvda

Issue:
Braille Cursor routing bring to the next characther
### Steps to reproduce:
Open a text editor, I tried notepad, thunderbird new message and this edit field on Google Chrome.
Press a cursor routing.
The cursor will be positioned a charachter after your desired position.
For example if you have the word NVDA, and you want the cursor to the D charachter, after pressing cursor routing you will be positioned on the A charachter.
This behaviour is present also if you select braille tether review cursor, instead of focus.



### Expected behavior:
Cursor should go to the proper charachter.

### Actual behavior:
Cursor's position is one charachter after you expect.



### System configuration:
NVDA version: next-14283,1e5c5581 (August 2, 2017).

NVDA Installed or portable: portable.

Other information:
running windows7 64bit with a Lilli display braille.

Name and version of other software in use when reproducing the issue:

Windows Notepad, Thunderbird38.

### Other questions:

Does the issue still occur after restarting your PC? Yes.

Have you tried any other versions of NVDA? YES, 2017.2 is broken too. 




Discussion:
Could you try this with a much older version of NVDA, e.g. 2016.3? This 
looks like an issue in the MDV Lilli driver. What braille table are you 
using?

Hello,
I have a very old NVDA 2014.2 installed on this pc, because I have no 
admin rights.
The problem is the same. My table is italian 8 dots, but I tried to 
change it to German or English unified braille, same thing. Cursor 
routing is always one charachter after the proper position.
So you assume it is a problem of lilli driver?
I will ask some friends to make some tests about it, they have that 
display braille.


[**@dreinn**](https://github.com/dreinn) commented on [2 aug. 2017 16:25 CEST](https://github.com/nvaccess/nvda/issues/7469#issuecomment-319688662 "2017-08-02T14:25:33Z - Replied by Github Reply Comments"):
> The problem is the same.

So it seems it has been there since the driver is there. Could you report what happens in Next if you press the cursor routing cell above cell 40?
@JCSTeh: Any idea whether we can track down the original authors of this Lilly driver?
There are two names on the copyright line for this driver, and although we don't do this with newer code, they include email addresses as well. I guess you could try contacting them.

That said, this looks like it might be a simple off by one bug. I'm guessing the driver returns 1-based routing indexes, but we expect 0-based. That could be easily tested if we provide a try build which logs the routing index pressed, then have affected users press specific routing keys and provide the log.
[**@jcsteh**](https://github.com/jcsteh) commented on [3 aug. 2017 01:20 CEST](https://github.com/nvaccess/nvda/issues/7469#issuecomment-319825083 "2017-08-02T23:20:20Z - Replied by Github Reply Comments"):
> That said, this looks like it might be a simple off by one bug. I'm guessing the driver returns 1-based routing indexes, but we expect 0-based.

Either that, or the key range that is reserved for routing according to the driver starts and ends one too high. The reserved key range is 257--296, Personally I'd start with 256 if I'd develop a protocol :) I also belief this is why hexadecimal values should be used for such numbers.
I made other test:
if I press routing38, it goes to 39, according with the mentioned bug.
Pressing 39 goes to 40.
Pressing 40 has no effect! The cursor remains on the last position, it 
can be cell 2 if it was the last place.

Pressing NVDA-1 and then cursor routing works well, because also  40 is 
announced as "route".

Yesterday I talked with a friend of mine that has Lilli display braille, 
and he has same problem.
We tried to understand if for some circumstances it could be an internal 
firmware issue, but with other screen readers, for example OSX, this 
issue is not present, so it should be a NVDA driver problem.
  Thanks for your patience!






Resolving patch:
diff --git a/source/brailleDisplayDrivers/lilli.py b/source/brailleDisplayDrivers/lilli.py
--- a/source/brailleDisplayDrivers/lilli.py
+++ b/source/brailleDisplayDrivers/lilli.py
@@ -2,7 +2,7 @@
 #A part of NonVisual Desktop Access (NVDA)
 #This file is covered by the GNU General Public License.
 #See the file COPYING for more details.
-#Copyright (C) 2008-2011 Gianluca Casalino <gianluca@spazioausili.net>, Alberto Benassati <benassati@cavazza.it>
+#Copyright (C) 2008-2017 NV Access Limited, Gianluca Casalino, Alberto Benassati, Babbage B.V.
 
 from logHandler import log
 from ctypes import *
@@ -19,9 +19,9 @@
 KEY_CHECK_INTERVAL = 50
 
 LILLI_KEYS = [
-	"", "F1", "F2", "F3", "F4",  "F5", "F6", "F7", "F8", "F9", "F10", "LF", "UP", "RG", "DN", "", 
-	"", "SF1", "SF2", "SF3", "SF4",  "SF5", "SF6", "SF7", "SF8", "SF9", "SF10", "SLF", "SUP", "SRG", "SDN", "", 
-	"", "LF1", "LF2", "LF3", "LF4",  "LF5", "LF6", "LF7", "LF8", "LF9", "LF10", "LLF", "LUP", "LRG", "LDN", "", 
+	"", "F1", "F2", "F3", "F4",  "F5", "F6", "F7", "F8", "F9", "F10", "LF", "UP", "RG", "DN", "",
+	"", "SF1", "SF2", "SF3", "SF4",  "SF5", "SF6", "SF7", "SF8", "SF9", "SF10", "SLF", "SUP", "SRG", "SDN", "",
+	"", "LF1", "LF2", "LF3", "LF4",  "LF5", "LF6", "LF7", "LF8", "LF9", "LF10", "LLF", "LUP", "LRG", "LDN", "",
 	"", "SLF1", "SLF2", "SLF3", "SLF4",  "SLF5", "SLF6", "SLF7", "SLF8", "SLF9", "SLF10", "SLLF", "SLUP", "SLRG", "SLDN", "SFDN", "SFUP",
 	"route"
 ]
@@ -76,21 +76,21 @@ def _handleKeyPresses(self):
 			except:
 				pass
 			if not key: break
-			if (key <= 64) or ((key >= 257) and (key <= 296)): 
+			if (key <= 0x40) or ((key >= 0x101) and (key <= 0x128)):
 				self._onKeyPress(key)
 
 	def _onKeyPress(self, key):
 		try:
-			if (key >= 257) and (key <= 296):                                 
-				inputCore.manager.executeGesture(InputGesture(LILLI_KEYS[65],key-256))
-			elif (key <= 64):
+			if (key >= 0x101) and (key <= 0x128):
+				inputCore.manager.executeGesture(InputGesture(LILLI_KEYS[65],key-0x101))
+			elif (key <= 0x40):
 				inputCore.manager.executeGesture(InputGesture(LILLI_KEYS[key],0))
 		except inputCore.NoInputGestureAction:
 			pass
 
 	def display(self, cells):
 		cells="".join(chr(lilliCellsMap[x]) for x in cells)
-		lilliDll.WriteBuf(cells) 
+		lilliDll.WriteBuf(cells)
 
 	gestureMap = inputCore.GlobalGestureMap({
 		"globalCommands.GlobalCommands": {


Test patch: