mirror of
https://github.com/lowobservable/oec.git
synced 2026-01-11 23:53:04 +00:00
Improve how keyboard is determined
This commit is contained in:
parent
2581b7bc6f
commit
074ffce9ed
@ -7,7 +7,7 @@ from coax import open_serial_interface, TerminalType
|
||||
|
||||
from .interface import InterfaceWrapper
|
||||
from .controller import Controller
|
||||
from .device import get_ids, get_features, UnsupportedDeviceError
|
||||
from .device import get_ids, get_features, get_keyboard_description, UnsupportedDeviceError
|
||||
from .terminal import Terminal
|
||||
from .tn3270 import TN3270Session
|
||||
|
||||
@ -19,9 +19,9 @@ if os.name == 'posix':
|
||||
|
||||
IS_VT100_AVAILABLE = True
|
||||
|
||||
from .keymap_3278_2 import KEYMAP as KEYMAP_3278_2
|
||||
from .keymap_3483 import KEYMAP as KEYMAP_3483
|
||||
from .keymap_3483_102 import KEYMAP as KEYMAP_3483_102
|
||||
from .keymap_3278_typewriter import KEYMAP as KEYMAP_3278_TYPEWRITER
|
||||
from .keymap_ibm_typewriter import KEYMAP as KEYMAP_IBM_TYPEWRITER
|
||||
from .keymap_ibm_enhanced import KEYMAP as KEYMAP_IBM_ENHANCED
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
@ -29,19 +29,15 @@ logger = logging.getLogger('oec.main')
|
||||
|
||||
CONTROLLER = None
|
||||
|
||||
def _get_keymap(terminal_id, extended_id):
|
||||
keymap = KEYMAP_3278_2
|
||||
def _get_keymap(keyboard_description):
|
||||
if keyboard_description.startswith('3278'):
|
||||
return KEYMAP_3278_TYPEWRITER
|
||||
elif keyboard_description.startswith('IBM-TYPEWRITER'):
|
||||
return KEYMAP_IBM_TYPEWRITER
|
||||
elif keyboard_description.startswith('IBM-ENHANCED'):
|
||||
return KEYMAP_IBM_ENHANCED
|
||||
|
||||
if extended_id == 'c1348300':
|
||||
keymap = KEYMAP_3483
|
||||
|
||||
if extended_id == 'c1348301':
|
||||
keymap = KEYMAP_3483_102
|
||||
|
||||
if extended_id == 'c1347200':
|
||||
keymap = KEYMAP_3483
|
||||
|
||||
return keymap
|
||||
return KEYMAP_3278_TYPEWRITER
|
||||
|
||||
def _get_character_encoding(encoding):
|
||||
try:
|
||||
@ -55,18 +51,23 @@ def _create_device(args, interface, device_address, poll_response):
|
||||
# Read the terminal identifiers.
|
||||
(terminal_id, extended_id) = get_ids(interface, device_address)
|
||||
|
||||
logger.info(f'Terminal ID = {terminal_id}, Extended ID = {extended_id}')
|
||||
logger.info(f'Terminal ID = {terminal_id}')
|
||||
logger.info(f'Extended ID = {extended_id}')
|
||||
|
||||
if terminal_id.type != TerminalType.CUT:
|
||||
raise UnsupportedDeviceError('Only CUT type terminals are supported')
|
||||
|
||||
keyboard_description = get_keyboard_description(terminal_id, extended_id)
|
||||
|
||||
logger.info(f'Keyboard = {keyboard_description}')
|
||||
|
||||
# Read the terminal features.
|
||||
features = get_features(interface, device_address)
|
||||
|
||||
logger.info(f'Features = {features}')
|
||||
|
||||
# Get the keymap.
|
||||
keymap = _get_keymap(terminal_id, extended_id)
|
||||
keymap = _get_keymap(keyboard_description)
|
||||
|
||||
logger.info(f'Keymap = {keymap.name}')
|
||||
|
||||
|
||||
@ -111,6 +111,65 @@ def get_features(interface, device_address):
|
||||
|
||||
return parse_features(ids, commands)
|
||||
|
||||
def get_keyboard_description(terminal_id, extended_id):
|
||||
is_3278 = extended_id is None or not int(extended_id[0:2], 16) & 0x80
|
||||
|
||||
if is_3278:
|
||||
description = '3278'
|
||||
|
||||
id_map = {
|
||||
0b0001: 'APL',
|
||||
0b0010: 'TEXT',
|
||||
0b0100: 'TYPEWRITER-PSHICO',
|
||||
0b0101: 'APL',
|
||||
0b0110: 'TEXT',
|
||||
0b0111: 'APL-PSHICO',
|
||||
0b1000: 'DATAENTRY-2',
|
||||
0b1001: 'DATAENTRY-1',
|
||||
0b1010: 'TYPEWRITER',
|
||||
0b1100: 'DATAENTRY-2',
|
||||
0b1101: 'DATAENTRY-1',
|
||||
0b1110: 'TYPEWRITER'
|
||||
}
|
||||
|
||||
if terminal_id.keyboard in id_map:
|
||||
description += '-' + id_map[terminal_id.keyboard]
|
||||
|
||||
return description
|
||||
|
||||
id_ = int(extended_id[0:2], 16) & 0x1f
|
||||
|
||||
is_user = int(extended_id[0:2], 16) & 0x20
|
||||
|
||||
if is_user:
|
||||
description = 'USER'
|
||||
|
||||
if id_ in [1, 2, 3, 4]:
|
||||
description += f'-{id_}'
|
||||
|
||||
return description
|
||||
|
||||
is_ibm = not int(extended_id[6:8], 16) & 0x80
|
||||
|
||||
description = 'IBM' if is_ibm else 'UNKNOWN'
|
||||
|
||||
is_enhanced = int(extended_id[6:8], 16) & 0x01
|
||||
|
||||
if is_enhanced:
|
||||
if id_ == 1:
|
||||
return description + '-ENHANCED'
|
||||
|
||||
return None
|
||||
|
||||
if id_ == 1:
|
||||
return description + '-TYPEWRITER'
|
||||
elif id_ == 2:
|
||||
return description + '-DATAENTRY'
|
||||
elif id_ == 3:
|
||||
return description + '-APL'
|
||||
|
||||
return None
|
||||
|
||||
def _jumbo_write_split_data(data, max_length, first_chunk_max_length_adjustment=-1):
|
||||
if max_length is None:
|
||||
return [data]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
"""
|
||||
oec.keymap_3278_2
|
||||
~~~~~~~~~~~~~~~~~
|
||||
oec.keymap_3278_typewriter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
"""
|
||||
|
||||
from .keyboard import Key, Keymap
|
||||
@ -198,4 +198,4 @@ MODIFIER_RELEASE_MAP = {
|
||||
207: Key.RIGHT_ALT
|
||||
}
|
||||
|
||||
KEYMAP = Keymap('3278-2', KEYMAP_DEFAULT, KEYMAP_SHIFT, KEYMAP_ALT, MODIFIER_RELEASE_MAP)
|
||||
KEYMAP = Keymap('3278 Typewriter', KEYMAP_DEFAULT, KEYMAP_SHIFT, KEYMAP_ALT, MODIFIER_RELEASE_MAP)
|
||||
@ -1,13 +1,10 @@
|
||||
"""
|
||||
oec.keymap_3483_102
|
||||
~~~~~~~~~~~~~~~
|
||||
oec.keymap_ibm_enhanced
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
"""
|
||||
|
||||
from .keyboard import Key, Keymap
|
||||
|
||||
# I have a 5250 keyboard for my 3483-V, this mapping is based on photographs
|
||||
# of the 3270 keyboard and may not be correct.
|
||||
|
||||
KEYMAP_DEFAULT = {
|
||||
# Function Keys
|
||||
7: Key.PF1,
|
||||
@ -240,4 +237,4 @@ KEYMAP_ALT = {
|
||||
106: Key.RIGHT_2
|
||||
}
|
||||
|
||||
KEYMAP = Keymap('3483_102', KEYMAP_DEFAULT, KEYMAP_SHIFT, KEYMAP_ALT, modifier_release=240)
|
||||
KEYMAP = Keymap('IBM Enhanced', KEYMAP_DEFAULT, KEYMAP_SHIFT, KEYMAP_ALT, modifier_release=240)
|
||||
@ -1,13 +1,10 @@
|
||||
"""
|
||||
oec.keymap_3483
|
||||
~~~~~~~~~~~~~~~
|
||||
oec.keymap_ibm_typewriter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
"""
|
||||
|
||||
from .keyboard import Key, Keymap
|
||||
|
||||
# I have a 5250 keyboard for my 3483-V, this mapping is based on photographs
|
||||
# of the 3270 keyboard and may not be correct.
|
||||
|
||||
KEYMAP_DEFAULT = {
|
||||
# Function Keys
|
||||
7: Key.PF1,
|
||||
@ -235,4 +232,4 @@ KEYMAP_ALT = {
|
||||
106: Key.RIGHT_2
|
||||
}
|
||||
|
||||
KEYMAP = Keymap('3483', KEYMAP_DEFAULT, KEYMAP_SHIFT, KEYMAP_ALT, modifier_release=240)
|
||||
KEYMAP = Keymap('IBM Typewriter', KEYMAP_DEFAULT, KEYMAP_SHIFT, KEYMAP_ALT, modifier_release=240)
|
||||
@ -8,7 +8,7 @@ from coax.protocol import TerminalId
|
||||
import context
|
||||
|
||||
from oec.interface import InterfaceWrapper
|
||||
from oec.device import address_commands, format_address, get_ids, get_features, _jumbo_write_split_data
|
||||
from oec.device import address_commands, format_address, get_ids, get_features, get_keyboard_description, _jumbo_write_split_data
|
||||
|
||||
from mock_interface import MockInterface
|
||||
|
||||
@ -161,6 +161,27 @@ class GetFeaturesTestCase(unittest.TestCase):
|
||||
# Assert
|
||||
self.assertEqual(features, { Feature.EAB: 7 })
|
||||
|
||||
class GetKeyboardDescriptionTestCase(unittest.TestCase):
|
||||
def test(self):
|
||||
CASES = [
|
||||
(10, None, '3278-TYPEWRITER'),
|
||||
(0, 'c1347200', 'IBM-TYPEWRITER'),
|
||||
(10, '41347200', '3278-TYPEWRITER'),
|
||||
(0, 'c2347200', 'IBM-DATAENTRY'),
|
||||
(0, 'c3347200', 'IBM-APL'),
|
||||
(0, 'c1348301', 'IBM-ENHANCED'),
|
||||
(0, 'e1347200', 'USER-1'),
|
||||
(0, 'e4347200', 'USER-4')
|
||||
]
|
||||
|
||||
for (keyboard, extended_id, expected_description) in CASES:
|
||||
with self.subTest(keyboard=keyboard, extended_id=extended_id):
|
||||
terminal_id = TerminalId(0b0000_0100 | (keyboard << 4))
|
||||
|
||||
description = get_keyboard_description(terminal_id, extended_id)
|
||||
|
||||
self.assertEqual(description, expected_description)
|
||||
|
||||
class JumboWriteSplitDataTestCase(unittest.TestCase):
|
||||
def test_no_split_strategy(self):
|
||||
for data in [bytes(range(0, 64)), (bytes.fromhex('00'), 64)]:
|
||||
|
||||
@ -9,7 +9,7 @@ import context
|
||||
from oec.interface import InterfaceWrapper
|
||||
from oec.terminal import Terminal
|
||||
from oec.display import Display, Dimensions, StatusLine, BufferedDisplay, encode_character, encode_string
|
||||
from oec.keymap_3278_2 import KEYMAP as KEYMAP_3278_2
|
||||
from oec.keymap_3278_typewriter import KEYMAP
|
||||
|
||||
from mock_interface import MockInterface
|
||||
|
||||
@ -833,7 +833,7 @@ def _create_display(interface):
|
||||
terminal_id = TerminalId(0b11110100)
|
||||
extended_id = 'c1348300'
|
||||
features = { }
|
||||
keymap = KEYMAP_3278_2
|
||||
keymap = KEYMAP
|
||||
|
||||
terminal = Terminal(InterfaceWrapper(interface), None, terminal_id, extended_id, features, keymap)
|
||||
|
||||
@ -845,7 +845,7 @@ def _create_buffered_display(interface, has_eab=False):
|
||||
terminal_id = TerminalId(0b11110100)
|
||||
extended_id = 'c1348300'
|
||||
features = { Feature.EAB: 7 } if has_eab else { }
|
||||
keymap = KEYMAP_3278_2
|
||||
keymap = KEYMAP
|
||||
|
||||
terminal = Terminal(InterfaceWrapper(interface), None, terminal_id, extended_id, features, keymap)
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@ import unittest
|
||||
import context
|
||||
|
||||
from oec.keyboard import KeyboardModifiers, Key, Keymap, Keyboard, get_character_for_key
|
||||
from oec.keymap_3278_2 import KEYMAP as KEYMAP_3278_2
|
||||
from oec.keymap_3483 import KEYMAP as KEYMAP_3483
|
||||
from oec.keymap_3278_typewriter import KEYMAP as KEYMAP_3278_TYPEWRITER
|
||||
from oec.keymap_ibm_typewriter import KEYMAP as KEYMAP_IBM_TYPEWRITER
|
||||
|
||||
class KeyboardModifiersTestCase(unittest.TestCase):
|
||||
def test_is_shift(self):
|
||||
@ -39,7 +39,7 @@ class KeyboardModifiersTestCase(unittest.TestCase):
|
||||
|
||||
class KeyboardGetKeySingleModifierReleaseTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.keyboard = Keyboard(KEYMAP_3483)
|
||||
self.keyboard = Keyboard(KEYMAP_IBM_TYPEWRITER)
|
||||
|
||||
def test_single_modifier_release_is_true(self):
|
||||
self.assertTrue(self.keyboard.single_modifier_release)
|
||||
@ -120,13 +120,13 @@ class KeyboardGetKeySingleModifierReleaseTestCase(unittest.TestCase):
|
||||
self._assert_get_key(240, None, KeyboardModifiers.NONE, False)
|
||||
self._assert_get_key(20, None, KeyboardModifiers.NONE, False)
|
||||
self._assert_get_key(36, Key.LOWER_E, KeyboardModifiers.NONE, False)
|
||||
|
||||
|
||||
def _assert_get_key(self, scan_code, key, modifiers, modifiers_changed):
|
||||
self.assertEqual(self.keyboard.get_key(scan_code), (key, modifiers, modifiers_changed))
|
||||
|
||||
class KeyboardGetKeyMultipleModifierReleaseTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.keyboard = Keyboard(KEYMAP_3278_2)
|
||||
self.keyboard = Keyboard(KEYMAP_3278_TYPEWRITER)
|
||||
|
||||
def test_single_modifier_release_is_false(self):
|
||||
self.assertFalse(self.keyboard.single_modifier_release)
|
||||
@ -196,7 +196,7 @@ class KeyboardGetKeyMultipleModifierReleaseTestCase(unittest.TestCase):
|
||||
self._assert_get_key(76, Key.CAPS_LOCK, KeyboardModifiers.NONE, True)
|
||||
self._assert_get_key(204, None, KeyboardModifiers.NONE, False)
|
||||
self._assert_get_key(100, Key.LOWER_E, KeyboardModifiers.NONE, False)
|
||||
|
||||
|
||||
def _assert_get_key(self, scan_code, key, modifiers, modifiers_changed):
|
||||
self.assertEqual(self.keyboard.get_key(scan_code), (key, modifiers, modifiers_changed))
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ from oec.interface import InterfaceWrapper
|
||||
from oec.device import UnsupportedDeviceError
|
||||
from oec.terminal import Terminal
|
||||
from oec.display import Display, StatusLine
|
||||
from oec.keymap_3278_2 import KEYMAP as KEYMAP_3278_2
|
||||
from oec.keymap_3278_typewriter import KEYMAP
|
||||
|
||||
from mock_interface import MockInterface
|
||||
|
||||
@ -19,7 +19,7 @@ class InitTerminalTestCase(unittest.TestCase):
|
||||
terminal_id = TerminalId(0b11110100)
|
||||
|
||||
# Act
|
||||
Terminal(None, None, terminal_id, None, { }, KEYMAP_3278_2)
|
||||
Terminal(None, None, terminal_id, None, { }, KEYMAP)
|
||||
|
||||
def test_unsupported_terminal_model(self):
|
||||
# Arrange
|
||||
@ -29,7 +29,7 @@ class InitTerminalTestCase(unittest.TestCase):
|
||||
|
||||
# Act and assert
|
||||
with self.assertRaises(UnsupportedDeviceError):
|
||||
Terminal(None, None, terminal_id, None, { }, KEYMAP_3278_2)
|
||||
Terminal(None, None, terminal_id, None, { }, KEYMAP)
|
||||
|
||||
class TerminalSetupTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@ -79,7 +79,7 @@ def _create_terminal(interface):
|
||||
terminal_id = TerminalId(0b11110100)
|
||||
extended_id = 'c1348300'
|
||||
features = { }
|
||||
keymap = KEYMAP_3278_2
|
||||
keymap = KEYMAP
|
||||
|
||||
terminal = Terminal(InterfaceWrapper(interface), None, terminal_id, extended_id, features, keymap)
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ from oec.interface import InterfaceWrapper
|
||||
from oec.terminal import Terminal
|
||||
from oec.display import Dimensions, BufferedDisplay, StatusLine
|
||||
from oec.keyboard import Key, KeyboardModifiers
|
||||
from oec.keymap_3278_2 import KEYMAP as KEYMAP_3278_2
|
||||
from oec.keymap_3278_typewriter import KEYMAP
|
||||
from oec.session import SessionDisconnectedError
|
||||
from oec.tn3270 import TN3270Session
|
||||
|
||||
@ -396,7 +396,7 @@ def _create_terminal(interface):
|
||||
terminal_id = TerminalId(0b11110100)
|
||||
extended_id = 'c1348300'
|
||||
features = { }
|
||||
keymap = KEYMAP_3278_2
|
||||
keymap = KEYMAP
|
||||
|
||||
terminal = Terminal(InterfaceWrapper(interface), None, terminal_id, extended_id, features, keymap)
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ from oec.interface import InterfaceWrapper
|
||||
from oec.terminal import Terminal
|
||||
from oec.display import Dimensions, BufferedDisplay
|
||||
from oec.keyboard import Key, KeyboardModifiers
|
||||
from oec.keymap_3278_2 import KEYMAP as KEYMAP_3278_2
|
||||
from oec.keymap_3278_typewriter import KEYMAP
|
||||
from oec.session import SessionDisconnectedError
|
||||
from oec.vt100 import VT100Session
|
||||
|
||||
@ -183,7 +183,7 @@ def _create_terminal(interface):
|
||||
terminal_id = TerminalId(0b11110100)
|
||||
extended_id = 'c1348300'
|
||||
features = { }
|
||||
keymap = KEYMAP_3278_2
|
||||
keymap = KEYMAP
|
||||
|
||||
terminal = Terminal(InterfaceWrapper(interface), None, terminal_id, extended_id, features, keymap)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user