From f0894c1bdeeb4bbf63f25947780b891af4b5cca3 Mon Sep 17 00:00:00 2001 From: Ross Wilson Date: Sat, 18 Jul 2015 12:42:27 +0700 Subject: [PATCH] Keyboard code working, not fully tested --- pymlac/Kbd.py | 85 ++++++++++++++++++++++++++++++++++++++++------ pymlac/test_KBD.py | 62 +++++++++++++++++++++++++++------ 2 files changed, 126 insertions(+), 21 deletions(-) diff --git a/pymlac/Kbd.py b/pymlac/Kbd.py index e4e1577..08a1cee 100644 --- a/pymlac/Kbd.py +++ b/pymlac/Kbd.py @@ -22,6 +22,24 @@ We must emulate funny Imlac key values. # # When the keyboard flag is cleard (either KCF or KRC instructions) the 8-bit # ASCII buffer is cleared but the three status bits R, C and S are left alone. +# +############################## +# +# The wxPython event provides the following keyboard events: +# wx.EVT_KEY_DOWN when a key is pressed +# wx.EVT_KEY_UP when a key is pressed +# wx.EVT_CHAR when a fully modified ASCII char value is found +# +# In this code we use the UP/DOWN events to keep track of the modifiers +# and we use the CHAR event to change the key buffer value. We do it this way +# because on the Imlac the modifiers (R, C and S flags) are seperate from the +# keyboard value and are not cleared by the KCF or KRC instructions. This means +# Imlac code could check for the modifier flags alone at any time, so we have to +# keep track of the modifiers which DON'T raise a CHAR event. We therefore need +# to handle the key UP/DOWN events for the modifiers. +# +# Since most modern keyboards don't have a REPEAT key (they use auto-repeat) the +# R flag will always be 0. class Kbd(object): @@ -77,27 +95,74 @@ class Kbd(object): '\000\206\204\205\210\202\217\216\000\214\000\000\000\000\000\000'#11 '\000\000\000\000\000\000\000\000\000\000\000\000\000') #12 + # define the keycode values for modifier keys + KeyShift = 0x0132 + KeyControl = 0x018c + + # modifier key flags + FlagR = 0 # REPEAT key, always 0 + FlagC = 0 # CONTROL key + FlagS = 0 # SHIFT key + def __init__(self): - self.kbd_buffer = 0 - self.modifiers = 0 self.clear() - def handle_down_event(self, event): - """Handle a KEY DOWN event from wxPython.""" + # .clear() doesn't clear flags + self.FlagR = 0 + self.FlagC = 0 + self.FlagS = 0 - print('DOWN: event=%s' % str(dir(event))) + def handle_down_event(self, event): + """Handle a KEY DOWN event from wxPython. + + This is only to track modifier keys. + """ + + modifiers = event.GetModifiers() + keycode = event.GetKeyCode() + + print('DOWN: Modifiers=%04x, GetKeyCode=%04x' % (modifiers, keycode)) + + if keycode == self.KeyShift: + self.FlagS = 1 + elif keycode == self.KeyControl: + self.FlagC = 1 + + event.Skip() def handle_up_event(self, event): - """Handle a KEY UP event from wxPython.""" + """Handle a KEY UP event from wxPython. - print('UP: event=%s' % str(dir(event))) + This is only to track modifier keys. + """ - def is_ready(self): - return self.ready + modifiers = event.GetModifiers() + keycode = event.GetKeyCode() + + print(' UP: Modifiers=%04x, GetKeyCode=%04x' % (modifiers, keycode)) + + if keycode == self.KeyShift: + self.FlagS = 0 + elif keycode == self.KeyControl: + self.FlagC = 0 + + event.Skip() + + def handle_char_event(self, event): + """Handle a CHAR key event.""" + + self.buffer = event.GetKeyCode() + print('NEW: %04x' % ord(self.buffer)) + self.ready = True def clear(self): + """Clear keyboard buffer and READY flag.""" + self.ready = False + self.buffer = 0 def read(self): - return self.kbd_buffer + """Read keyboard buffer and modifier keys.""" + + return (self.buffer & 0xff) + (self.FlagC << 9) + (self.FlagS << 8) diff --git a/pymlac/test_KBD.py b/pymlac/test_KBD.py index 7e349a9..cadf996 100644 --- a/pymlac/test_KBD.py +++ b/pymlac/test_KBD.py @@ -8,6 +8,7 @@ Usage: test_KBD.py [-h] """ +import string import wx import Kbd @@ -44,8 +45,17 @@ class TestFrame(wx.Frame): # build the GUI box = wx.BoxSizer(wx.VERTICAL) + self.display = wx.TextCtrl(self.panel) box.Add(self.display, proportion=1, border=1, flag=wx.EXPAND) + + btnSizer = wx.BoxSizer(wx.HORIZONTAL) + clearBtn = wx.Button(self.panel, wx.ID_ANY, 'Clear') + readBtn = wx.Button(self.panel, wx.ID_ANY, 'Read') + btnSizer.Add(clearBtn, 0, wx.ALL, 5) + btnSizer.Add(readBtn, 0, wx.ALL, 5) + box.Add(btnSizer, 0, wx.ALL, 5) + self.panel.SetSizer(box) self.panel.Layout() self.Centre() @@ -53,28 +63,58 @@ class TestFrame(wx.Frame): self.display.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.display.Bind(wx.EVT_KEY_UP, self.OnKeyUp) + self.display.Bind(wx.EVT_CHAR, self.OnChar) + + clearBtn.Bind(wx.EVT_BUTTON, self.onClear) + readBtn.Bind(wx.EVT_BUTTON, self.onRead) + + def onClear(self, event): + """Handle a CLEAR operation.""" + + self.kbd.clear() + + def onRead(self, event): + """Handle a READ operation.""" + + value = self.kbd.read() + char = value & 0xff + char_str = chr(char) + if char_str not in string.printable: + char_str = '' + R = (value >> 10) & 0x01 + C = (value >> 9) & 0x01 + S = (value >> 8) & 0x01 + + self.display.AppendText('R=%d, C=%d, S=%d, char=%04o (%s)\n' + % (R, C, S, char, char_str)) + self.display.Refresh() + def OnKeyDown(self, event): """Handle a "key down" event.""" - self.kbd.handle_down_event(event) - -# log('event=%s' % str(dir(event))) -# self.display.AppendText('DOWN: Modifiers=%04x, GetKeyCode=%02x, UnicodeKey=%s\n' -# % (event.GetModifiers(), -# event.GetKeyCode(), -# str(event.GetUnicodeKey()))) +# self.display.AppendText('DOWN: Modifiers=%04x, GetKeyCode=%04x\n' +# % (event.GetModifiers(), event.GetKeyCode())) # self.display.Refresh() -# if wx.WXK_LEFT == event.GetKeyCode(): -# print('LEFT key') + + self.kbd.handle_down_event(event) def OnKeyUp(self, event): """Handle a "key up" event.""" +# self.display.AppendText('UP: Modifiers=%04x, GetKeyCode=%04x\n' +# % (event.GetModifiers(), event.GetKeyCode())) +# self.display.Refresh() + self.kbd.handle_up_event(event) -# print('UP: Modifiers=%s, GetKeyCode=%s, UnicodeKey=%s' -# % (str(event.GetModifiers()), str(event.GetKeyCode()), str(event.GetUnicodeKey()))) + def OnChar(self, event): + """Handle a "char" event.""" + + print('CHAR: Modifiers=%04x, GetKeyCode=%04x' + % (event.GetModifiers(), event.GetKeyCode())) + + self.kbd.handle_char_event(event) ################################################################################