openMSX
Keyboard.hh
Go to the documentation of this file.
1 #ifndef KEYBOARD_HH
2 #define KEYBOARD_HH
3 
4 #include "KeyboardSettings.hh"
5 #include "UnicodeKeymap.hh"
6 #include "MSXEventListener.hh"
7 #include "StateChangeListener.hh"
8 #include "Schedulable.hh"
9 #include "RecordedCommand.hh"
10 #include "SimpleDebuggable.hh"
11 #include "EventListener.hh"
12 #include "serialize_meta.hh"
13 #include "span.hh"
14 #include "openmsx.hh"
15 #include <array>
16 #include <deque>
17 #include <string_view>
18 #include <vector>
19 #include <memory>
20 
21 namespace openmsx {
22 
23 class MSXMotherBoard;
24 class Scheduler;
25 class CommandController;
26 class DeviceConfig;
27 class EventDistributor;
28 class MSXEventDistributor;
29 class StateChangeDistributor;
30 class KeyEvent;
31 class StateChange;
32 class TclObject;
33 class Interpreter;
34 
35 class Keyboard final : private MSXEventListener, private StateChangeListener
36  , private Schedulable
37 {
38 public:
40 
51  Keyboard(MSXMotherBoard& motherBoard, Scheduler& scheduler,
52  CommandController& commandController,
53  EventDistributor& eventDistributor,
54  MSXEventDistributor& msxEventDistributor,
55  StateChangeDistributor& stateChangeDistributor,
56  MatrixType matrix, const DeviceConfig& config);
57 
58  ~Keyboard();
59 
62  const byte* getKeys() const;
63 
64  void transferHostKeyMatrix(const Keyboard& source);
65 
66  template<typename Archive>
67  void serialize(Archive& ar, unsigned version);
68 
69 private:
70  // MSXEventListener
71  void signalMSXEvent(const std::shared_ptr<const Event>& event,
72  EmuTime::param time) override;
73  // StateChangeListener
74  void signalStateChange(const std::shared_ptr<StateChange>& event) override;
75  void stopReplay(EmuTime::param time) override;
76 
77  // Schedulable
78  void executeUntil(EmuTime::param time) override;
79 
80  void pressKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
81  void releaseKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
82  void changeKeyMatrixEvent (EmuTime::param time, byte row, byte newValue);
83 
84  void processCapslockEvent(EmuTime::param time, bool down);
85  void processCodeKanaChange(EmuTime::param time, bool down);
86  void processGraphChange(EmuTime::param time, bool down);
87  void processKeypadEnterKey(EmuTime::param time, bool down);
88  void processSdlKey(EmuTime::param time, bool down, Keys::KeyCode key);
89  bool processQueuedEvent(const Event& event, EmuTime::param time);
90  bool processKeyEvent(EmuTime::param time, bool down, const KeyEvent& keyEvent);
91  void updateKeyMatrix(EmuTime::param time, bool down, KeyMatrixPosition pos);
92  void processCmd(Interpreter& interp, span<const TclObject> tokens, bool up);
93  bool pressUnicodeByUser(
94  EmuTime::param time, UnicodeKeymap::KeyInfo keyInfo, unsigned unicode,
95  bool down);
96  int pressAscii(unsigned unicode, bool down);
97  void pressLockKeys(byte lockKeysMask, bool down);
98  bool commonKeys(unsigned unicode1, unsigned unicode2);
99  void debug(const char* format, ...);
100 
105  byte needsLockToggle(const UnicodeKeymap::KeyInfo& keyInfo) const;
106 
107  CommandController& commandController;
108  MSXEventDistributor& msxEventDistributor;
109  StateChangeDistributor& stateChangeDistributor;
110 
111  static constexpr int MAX_KEYSYM = 0x150;
112  static const KeyMatrixPosition keyTabs[][MAX_KEYSYM];
113  const KeyMatrixPosition* keyTab;
114 
115  const std::array<KeyMatrixPosition, UnicodeKeymap::KeyInfo::NUM_MODIFIERS>& modifierPos;
116 
117  struct KeyMatrixUpCmd final : RecordedCommand {
118  KeyMatrixUpCmd(CommandController& commandController,
119  StateChangeDistributor& stateChangeDistributor,
120  Scheduler& scheduler);
121  void execute(span<const TclObject> tokens, TclObject& result,
122  EmuTime::param time) override;
123  std::string help(const std::vector<std::string>& tokens) const override;
124  } keyMatrixUpCmd;
125 
126  struct KeyMatrixDownCmd final : RecordedCommand {
127  KeyMatrixDownCmd(CommandController& commandController,
128  StateChangeDistributor& stateChangeDistributor,
129  Scheduler& scheduler);
130  void execute(span<const TclObject> tokens, TclObject& result,
131  EmuTime::param time) override;
132  std::string help(const std::vector<std::string>& tokens) const override;
133  } keyMatrixDownCmd;
134 
135  class KeyInserter final : public RecordedCommand, public Schedulable {
136  public:
137  KeyInserter(CommandController& commandController,
138  StateChangeDistributor& stateChangeDistributor,
139  Scheduler& scheduler);
140  bool isActive() const { return pendingSyncPoint(); }
141  template<typename Archive>
142  void serialize(Archive& ar, unsigned version);
143 
144  private:
145  void type(std::string_view str);
146  void reschedule(EmuTime::param time);
147 
148  // Command
149  void execute(span<const TclObject> tokens, TclObject& result,
150  EmuTime::param time) override;
151  std::string help(const std::vector<std::string>& tokens) const override;
152  void tabCompletion(std::vector<std::string>& tokens) const override;
153 
154  // Schedulable
155  void executeUntil(EmuTime::param time) override;
156 
157  std::string text_utf8;
158  unsigned last;
159  byte lockKeysMask;
160  bool releaseLast;
161  byte oldLocksOn;
162 
163  bool releaseBeforePress;
164  int typingFrequency;
165  } keyTypeCmd;
166 
167  class CapsLockAligner final : private EventListener, private Schedulable {
168  public:
169  CapsLockAligner(EventDistributor& eventDistributor,
170  Scheduler& scheduler);
171  ~CapsLockAligner();
172 
173  private:
174  // EventListener
175  int signalEvent(const std::shared_ptr<const Event>& event) override;
176 
177  // Schedulable
178  void executeUntil(EmuTime::param time) override;
179 
180  void alignCapsLock(EmuTime::param time);
181 
182  EventDistributor& eventDistributor;
183 
184  enum CapsLockAlignerStateType {
185  MUST_ALIGN_CAPSLOCK, MUST_DISTRIBUTE_KEY_RELEASE, IDLE
186  } state;
187  } capsLockAligner;
188 
189  KeyboardSettings keyboardSettings;
190 
191  class MsxKeyEventQueue final : public Schedulable {
192  public:
193  MsxKeyEventQueue(Scheduler& scheduler, Interpreter& interp);
194  void process_asap(EmuTime::param time,
195  const std::shared_ptr<const Event>& event);
196  void clear();
197  template<typename Archive>
198  void serialize(Archive& ar, unsigned version);
199  private:
200  // Schedulable
201  void executeUntil(EmuTime::param time) override;
202  std::deque<std::shared_ptr<const Event>> eventQueue;
203  Interpreter& interp;
204  } msxKeyEventQueue;
205 
206  struct KeybDebuggable final : SimpleDebuggable {
207  explicit KeybDebuggable(MSXMotherBoard& motherBoard);
208  byte read(unsigned address) override;
209  void write(unsigned address, byte value) override;
210  } keybDebuggable;
211 
212  UnicodeKeymap unicodeKeymap;
213  unsigned dynKeymap[MAX_KEYSYM];
214 
216  byte cmdKeyMatrix [KeyMatrixPosition::NUM_ROWS];
218  byte typeKeyMatrix [KeyMatrixPosition::NUM_ROWS];
220  byte userKeyMatrix[KeyMatrixPosition::NUM_ROWS];
222  byte hostKeyMatrix[KeyMatrixPosition::NUM_ROWS];
224  mutable byte keyMatrix[KeyMatrixPosition::NUM_ROWS];
225 
226  byte msxmodifiers;
227 
229  const bool hasKeypad;
233  const bool blockRow11;
235  const bool keyGhosting;
237  const bool keyGhostingSGCprotected;
241  const byte modifierIsLock;
242  mutable bool keysChanged;
247  byte locksOn;
248 };
250 
251 } // namespace openmsx
252 
253 #endif
openmsx::KeyEvent
Definition: InputEvents.hh:27
openmsx.hh
openmsx::IDLE
constexpr auto IDLE
Definition: WD2793.cc:40
openmsx::Scheduler
Definition: Scheduler.hh:34
openmsx::CommandController
Definition: CommandController.hh:18
StateChangeListener.hh
openmsx::Event
Definition: Event.hh:84
openmsx::Keyboard::Keyboard
Keyboard(MSXMotherBoard &motherBoard, Scheduler &scheduler, CommandController &commandController, EventDistributor &eventDistributor, MSXEventDistributor &msxEventDistributor, StateChangeDistributor &stateChangeDistributor, MatrixType matrix, const DeviceConfig &config)
Constructs a new Keyboard object.
Definition: Keyboard.cc:119
openmsx::MSXEventDistributor
Definition: MSXEventDistributor.hh:14
openmsx::DeviceConfig
Definition: DeviceConfig.hh:20
serialize_meta.hh
openmsx::Keyboard::serialize
void serialize(Archive &ar, unsigned version)
Definition: Keyboard.cc:1347
openmsx::MSXEventListener
Definition: MSXEventListener.hh:12
EventListener.hh
openmsx::StateChangeDistributor
Definition: StateChangeDistributor.hh:15
openmsx::Schedulable
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:34
openmsx::Keyboard::~Keyboard
~Keyboard()
Definition: Keyboard.cc:170
Schedulable.hh
openmsx::KeyMatrixPosition
A position (row, column) in a keyboard matrix.
Definition: UnicodeKeymap.hh:14
openmsx::Schedulable::Schedulable
Schedulable(const Schedulable &)=delete
openmsx::SimpleDebuggable::write
virtual void write(unsigned address, byte value, EmuTime::param time)
Definition: SimpleDebuggable.cc:49
openmsx::EventDistributor
Definition: EventDistributor.hh:17
openmsx::KeyMatrixPosition::NUM_ROWS
static constexpr unsigned NUM_ROWS
Rows are in the range [0..NUM_ROWS).
Definition: UnicodeKeymap.hh:19
span
Definition: span.hh:126
openmsx::SERIALIZE_CLASS_VERSION
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
openmsx::Keyboard::transferHostKeyMatrix
void transferHostKeyMatrix(const Keyboard &source)
Definition: Keyboard.cc:248
openmsx::SimpleDebuggable::read
virtual byte read(unsigned address, EmuTime::param time)
Definition: SimpleDebuggable.cc:39
openmsx::Keyboard::MATRIX_CVJOY
@ MATRIX_CVJOY
Definition: Keyboard.hh:39
RecordedCommand.hh
openmsx::Keyboard::MatrixType
MatrixType
Definition: Keyboard.hh:39
MSXEventListener.hh
openmsx::MSXMotherBoard
Definition: MSXMotherBoard.hh:60
openmsx::Schedulable::pendingSyncPoint
bool pendingSyncPoint() const
Definition: Schedulable.cc:38
openmsx::Keyboard::MATRIX_SVI
@ MATRIX_SVI
Definition: Keyboard.hh:39
openmsx::Keyboard::getKeys
const byte * getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition: Keyboard.cc:233
openmsx::Keyboard
Definition: Keyboard.hh:37
SimpleDebuggable.hh
openmsx::UnicodeKeymap::KeyInfo
Definition: UnicodeKeymap.hh:99
span.hh
KeyboardSettings.hh
openmsx::RecordedCommand
Commands that directly influence the MSX state should send and events so that they can be recorded by...
Definition: RecordedCommand.hh:46
UnicodeKeymap.hh
openmsx::Scheduler
Scheduler
Definition: Scheduler.cc:132
openmsx::TclObject
Definition: TclObject.hh:22
openmsx::Keys::KeyCode
KeyCode
Constants that identify keys and key modifiers.
Definition: Keys.hh:26
openmsx::Interpreter
Definition: Interpreter.hh:17
openmsx
This file implemented 3 utility functions:
Definition: Autofire.cc:5
openmsx::StateChangeListener
Definition: StateChangeListener.hh:12
openmsx::Keyboard::MATRIX_MSX
@ MATRIX_MSX
Definition: Keyboard.hh:39