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

BrailleNote: support for QT and Apex BT scroll wheel #6316

Merged
merged 16 commits into from Jun 13, 2018
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Empty file modified source/appModules/win32calc.py 100755 → 100644
Empty file.
135 changes: 98 additions & 37 deletions source/brailleDisplayDrivers/brailleNote.py
Expand Up @@ -2,11 +2,11 @@
#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) 2011-2017 Rui Batista, NV Access Limited
# Copyright (C) 2011-2017 NV access Limited, Rui Batista, Joseph Lee

""" Braille Display driver for the BrailleNote notetakers in terminal mode.
USB, serial and bluetooth communications are supported.
QWERTY keyboard input and scroll weels are not yet supported.
QWERTY keyboard input using basic terminal mode (no PC keyboard emulation) and scroll wheel are supported.
"""
from collections import OrderedDict
import itertools
Expand All @@ -30,7 +30,7 @@
BAUD_RATE = 38400
TIMEOUT = 0.1

# Tags sent by the braillenote
# Tags sent by the BrailleNote
# Combinations of dots 1...6
DOTS_TAG = 0x80
# combinations of dots 1...6 plus the space bar
Expand All @@ -39,12 +39,22 @@
DOTS_BACKSPACE_TAG = 0x82
# Combinations of dots 1..6 plus space bar and enter
DOTS_ENTER_TAG = 0x83
# Combinations of one or two Thunb keys
THUNB_KEYS_TAG = 0x84
# Combinations of one or two Thumb keys
THUMB_KEYS_TAG = 0x84
# Cursor Routing keys
CURSOR_KEY_TAG = 0x85
# Status
# Status
STATUS_TAG = 0x86
# Scroll Wheel (Apex BT)
SCROLL_WHEEL_TAG = 0x8B
# QWERTY keyboard
QT_LETTER_TAG = 0x8C
QT_MOD_TAG = 0x8D
QT_LETTER = 0x0
QT_FN = 0x1
QT_SHIFT = 0x2
QT_CTRL = 0x4
QT_READ = 0x8 #Alt key

DESCRIBE_TAG = "\x1B?"
DISPLAY_TAG = "\x1bB"
Expand All @@ -60,7 +70,7 @@
DOT_7 = 0x40
DOT_8 = 0x80

# Thumb keys
# Thumb-keys
THUMB_PREVIOUS = 0x01
THUMB_BACK = 0x02
THUMB_ADVANCE = 0x04
Expand All @@ -74,13 +84,48 @@
0 : "space"
}

# Scroll wheel components (Apex BT)
_scrWheel = ("wcounterclockwise", "wclockwise", "wup", "wdown", "wleft", "wright", "wcenter")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To improve consistency, could you rename these to wCounterclockwise, wClockwise, wUp, etc?


# Dots:
# Backspace is dot7 and enter dot8
_dotNames = {}
for i in xrange(1,9):
key = globals()["DOT_%d" % i]
_dotNames[key] = "d%d" % i

# QT keys
_qtKeyNames={
QT_FN : "function",
QT_SHIFT : "shift",
QT_CTRL : "ctrl",
QT_READ : "read"
}

# QT uses various ASCII characters for special keys, akin to scancodes.
_qtKeys= {
8:"backspace",
9:"tab",
13:"enter",
32:"space",
37:"leftArrow",
38:"upArrow",
39:"rightArrow",
40:"downArrow",
46:"delete",
186:"semi",
187:"equals",
188:"comma",
189:"hyphen",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd call this dash

190:"period",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd call this dot.

191:"slash",
192:"graav",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd call this grave

219:"leftBracket",
220:"backslash",
221:"rightBracket",
222:"tick",
}


class BrailleDisplayDriver(braille.BrailleDisplayDriver):
name = "brailleNote"
Expand Down Expand Up @@ -190,22 +235,33 @@ def _onReceive(self, command):
if not arg:
log.debugWarning("Timeout reading argument for command 0x%X" % command)
return
self._dispatch(command, ord(arg))
# #5993: Read the buffer once more if a BrailleNote QT says it's got characters in its pipeline.
if command == QT_MOD_TAG:
key = self._serial.read(2)[-1]
arg2 = _qtKeys.get(ord(key), key)
else:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could simplify this to: arg2 = _qtKeys.get(ord(key), key)

arg2 = None
self._dispatch(command, ord(arg), ord(arg2) if arg2 is not None else None)

def _dispatch(self, command, arg):
def _dispatch(self, command, arg, arg2=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data -> arg2. Also, maybe passed instead of invoked?

space = False
if command == THUNB_KEYS_TAG :
if command == THUMB_KEYS_TAG:
gesture = InputGesture(keys=arg)
elif command == SCROLL_WHEEL_TAG:
gesture = InputGesture(wheel=arg)
elif command == CURSOR_KEY_TAG:
gesture = InputGesture(routing=arg)
elif command in (DOTS_TAG, DOTS_SPACE_TAG, DOTS_ENTER_TAG, DOTS_BACKSPACE_TAG):
if command != DOTS_TAG:
space = True
if command == DOTS_ENTER_TAG:
# Stuppid bug in the implementation
# Stupid bug in the implementation
# Force dot8 here, although it should be already there
arg |= DOT_8
gesture = InputGesture(dots=arg, space=space)
elif command == QT_MOD_TAG:
# BrailleNote QT
gesture = InputGesture(qtMod=arg, qtData=arg2)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you actually considered making this a keyboardHandler.KeyboardInputGesture?

else:
log.debugWarning("Unknown command")
return
Expand All @@ -227,46 +283,51 @@ def display(self, cells):
"braille_nextLine": ("br(braillenote):tnext",),
"braille_routeTo": ("br(braillenote):routing",),
"braille_toggleTether": ("br(braillenote):tprevious+tnext",),
"kb:upArrow": ("br(braillenote):space+d1",),
"kb:downArrow": ("br(braillenote):space+d4",),
"kb:leftArrow": ("br(braillenote):space+d3",),
"kb:rightArrow": ("br(braillenote):space+d6",),
"kb:pageup": ("br(braillenote):space+d1+d3",),
"kb:pagedown": ("br(braillenote):space+d4+d6",),
"kb:home": ("br(braillenote):space+d1+d2",),
"kb:end": ("br(braillenote):space+d4+d5",),
"kb:control+home": ("br(braillenote):space+d1+d2+d3",),
"kb:control+end": ("br(braillenote):space+d4+d5+d6",),
"braille_enter": ("br(braillenote):space+d8",),
"kb:shift+tab": ("br(braillenote):space+d1+d2+d5+d6",),
"kb:tab": ("br(braillenote):space+d2+d3+d4+d5",),
"braille_eraseLastCell": ("br(braillenote):space+d7",),
"showGui": ("br(braillenote):space+d1+d3+d4+d5",),
"kb:windows": ("br(braillenote):space+d2+d4+d5+d6",),
"kb:alt": ("br(braillenote):space+d1+d3+d4",),
"toggleInputHelp": ("br(braillenote):space+d2+d3+d6",),
"kb:upArrow": ("br(braillenote):space+d1", "br(braillenote):wup", "br(braillenote):upArrow",),
"kb:downArrow": ("br(braillenote):space+d4", "br(braillenote):wdown","br(braillenote):downArrow",),
"kb:leftArrow": ("br(braillenote):space+d3","br(braillenote):wleft","br(braillenote):leftArrow",),
"kb:rightArrow": ("br(braillenote):space+d6","br(braillenote):wright","br(braillenote):rightArrow",),
"kb:pageup": ("br(braillenote):space+d1+d3","br(braillenote):function+upArrow",),
"kb:pagedown": ("br(braillenote):space+d4+d6","br(braillenote):function+downArrow",),
"kb:home": ("br(braillenote):space+d1+d2","br(braillenote):function+leftArrow",),
"kb:end": ("br(braillenote):space+d4+d5","br(braillenote):function+rightArrow",),
"kb:control+home": ("br(braillenote):space+d1+d2+d3","br(braillenote):read+T",),
"kb:control+end": ("br(braillenote):space+d4+d5+d6","br(braillenote):read+B",),
"braille_enter": ("br(braillenote):space+d8","br(braillenote):wcenter","br(braillenote):enter",),
"kb:shift+tab": ("br(braillenote):space+d1+d2+d5+d6","br(braillenote):wcounterclockwise","br(braillenote):shift+tab",),
"kb:tab": ("br(braillenote):space+d2+d3+d4+d5","br(braillenote):wclockwise","br(braillenote):tab",),
"braille_eraseLastCell": ("br(braillenote):space+d7","br(braillenote):backspace",),
"showGui": ("br(braillenote):space+d1+d3+d4+d5","br(braillenote):read+N",),
"kb:windows": ("br(braillenote):space+d2+d4+d5+d6","br(braillenote):read+W",),
"kb:alt": ("br(braillenote):space+d1+d3+d4","br(braillenote):read+M",),
"toggleInputHelp": ("br(braillenote):space+d2+d3+d6","br(braillenote):read+1",),
},
})

class InputGesture(braille.BrailleDisplayGesture, brailleInput.BrailleInputGesture):
source = BrailleDisplayDriver.name

def __init__(self, keys=None, dots=None, space=False, routing=None):
def __init__(self, keys=None, dots=None, space=False, routing=None, wheel=None, qtMod=None, qtData=None):
super(braille.BrailleDisplayGesture, self).__init__()
# see what thumb keys are pressed:
# Denotes if we're dealing with a QT model.
self.qt = qtMod is not None
# Handle thumb-keys and scroll wheel (wheel is for Apex BT).
names = set()
if keys is not None:
names.update(_keyNames[1 << i] for i in xrange(4)
if (1 << i) & keys)
names.update(_keyNames[1 << i] for i in xrange(4) if (1 << i) & keys)
elif wheel is not None:
names.add(_scrWheel[wheel])
elif dots is not None:
# now the dots
self.dots = dots
if space:
self.space = space
names.add(_keyNames[0])
names.update(_dotNames[1 << i] for i in xrange(8)
if (1 << i) & dots)
names.update(_dotNames[1 << i] for i in xrange(8) if (1 << i) & dots)
elif routing is not None:
self.routingIndex = routing
names.add('routing')
self.id = "+".join(names)
elif qtMod is not None:
names.update(_qtKeyNames[1 << i] for i in xrange(4)
if (1 << i) & qtMod)
names.add(qtData)
self.id = "+".join(names)
Expand Down
42 changes: 42 additions & 0 deletions user_docs/en/userGuide.t2t
Expand Up @@ -2348,6 +2348,11 @@ The following models are supported:
- BrailleNote Apex (USB and Bluetooth connections)
-

Except for BrailleNote PK, both braille (BT) and QWERTY (QT) keyboards are supported.
For BrailleNote QT, PC keyboard emulation isn't supported.
You can also enter braille dots using the QT keyboard.
Please check the braille terminal section of the BrailleNote manual guide for details.

If your device supports more than one type of connection, when connecting your BrailleNote to NVDA, you must set the braille terminal port in braille terminal options.
Please check the BrailleNote manual for details.
In NVDA, you may also need to set the port in the Braille Settings dialog.
Expand All @@ -2356,6 +2361,9 @@ If connecting using a legacy serial port (or a USB to serial converter) or if no

Before connecting your BrailleNote Apex using its USB client interface, you must install the drivers provided by HumanWare.

On the BrailleNote Apex BT, you can use the scroll wheel located between dots 1 and 4 for various NVDA commands.
The wheel consists of four directional dots, a center click button, and a wheel that spins clockwise or counterclockwise.

Following are the BrailleNote command assignments for NVDA.
Please check your BrailleNote's documentation to find where these keys are located.

Expand All @@ -2366,6 +2374,7 @@ Please check your BrailleNote's documentation to find where these keys are locat
| Move braille display to previous line | previous |
| Move braille display to next line | next |
| Route to braille cell | routing |
| NvDA menu | space+dot1+dot3+dot4+dot5 (space+n) |
| Toggle braille tethered to | previous+next |
| Up arrow key | space+dot1 |
| Down arrow key | space+dot4 |
Expand All @@ -2385,6 +2394,39 @@ Please check your BrailleNote's documentation to find where these keys are locat
| Windows key | space+dot2+dot4+dot5+dot6 (space+w) |
| Alt key | space+dot1+dot3+dot4 (space+m) |
| Toggle input help | space+dot2+dot3+dot6 (space+lower h) |

Following are commands assigned to BrailleNote QT when it is not in braille input mode.

|| Name | Key |
| NvDA menu | read+n |
| Up arrow key | upArrow |
| Down arrow key | downArrow |
| Left Arrow key | leftArrow|
| Right arrow key | rightArrow |
| Page up key | function+upArrow |
| Page down key | function+downArrow |
| Home key | function+leftArrow |
| End key | function+rightArrow |
| Control+home keys | read+t |
| Control+end keys | read+b |
| Enter key | enter |
| Backspace key | backspace |
| Tab key | tab |
| Shift+tab keys | shift+tab |
| Windows key | read+w |
| Alt key | read+m |
| Toggle input help | read+1 |

Following are commands assigned to the scroll wheel:

|| Name | Key |
| Up arrow key | upArrow |
| Down arrow key | downArrow |
| Left Arrow key | leftArrow |
| Right arrow key | rightArrow |
| Enter key | center button |
| Tab key | scroll wheel clockwise |
| Shift+tab keys | scroll wheel counterclockwise |
%kc:endInclude

++ EcoBraille ++
Expand Down