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 "Event.hh"
12 #include "EventListener.hh"
13 #include "serialize_meta.hh"
14 #include "openmsx.hh"
15 #include <array>
16 #include <deque>
17 #include <memory>
18 #include <span>
19 #include <string_view>
20 #include <vector>
21 
22 namespace openmsx {
23 
24 class MSXMotherBoard;
25 class Scheduler;
26 class CommandController;
27 class DeviceConfig;
28 class EventDistributor;
29 class MSXEventDistributor;
30 class StateChangeDistributor;
31 class StateChange;
32 class TclObject;
33 class Interpreter;
34 
35 class Keyboard final : private MSXEventListener, private StateChangeListener
36  , private Schedulable
37 {
38 public:
39  static constexpr int MAX_KEYSYM = 0x150;
41 
52  Keyboard(MSXMotherBoard& motherBoard, Scheduler& scheduler,
53  CommandController& commandController,
54  EventDistributor& eventDistributor,
55  MSXEventDistributor& msxEventDistributor,
56  StateChangeDistributor& stateChangeDistributor,
57  MatrixType matrix, const DeviceConfig& config);
58 
59  ~Keyboard();
60 
63  [[nodiscard]] const byte* getKeys() const;
64 
65  void transferHostKeyMatrix(const Keyboard& source);
66 
67  template<typename Archive>
68  void serialize(Archive& ar, unsigned version);
69 
70 private:
71  // MSXEventListener
72  void signalMSXEvent(const Event& event,
73  EmuTime::param time) noexcept override;
74  // StateChangeListener
75  void signalStateChange(const StateChange& event) override;
76  void stopReplay(EmuTime::param time) noexcept override;
77 
78  // Schedulable
79  void executeUntil(EmuTime::param time) override;
80 
81  void pressKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
82  void releaseKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
83  void changeKeyMatrixEvent (EmuTime::param time, byte row, byte newValue);
84 
85  void processCapslockEvent(EmuTime::param time, bool down);
86  void processCodeKanaChange(EmuTime::param time, bool down);
87  void processGraphChange(EmuTime::param time, bool down);
88  void processKeypadEnterKey(EmuTime::param time, bool down);
89  void processSdlKey(EmuTime::param time, bool down, Keys::KeyCode key);
90  bool processQueuedEvent(const Event& event, EmuTime::param time);
91  bool processKeyEvent(EmuTime::param time, bool down, const KeyEvent& keyEvent);
92  void updateKeyMatrix(EmuTime::param time, bool down, KeyMatrixPosition pos);
93  void processCmd(Interpreter& interp, std::span<const TclObject> tokens, bool up);
94  bool pressUnicodeByUser(
95  EmuTime::param time, UnicodeKeymap::KeyInfo keyInfo, unsigned unicode,
96  bool down);
97  int pressAscii(unsigned unicode, bool down);
98  void pressLockKeys(byte lockKeysMask, bool down);
99  bool commonKeys(unsigned unicode1, unsigned unicode2);
100  void debug(const char* format, ...);
101 
106  byte needsLockToggle(const UnicodeKeymap::KeyInfo& keyInfo) const;
107 
108 private:
109  CommandController& commandController;
110  MSXEventDistributor& msxEventDistributor;
111  StateChangeDistributor& stateChangeDistributor;
112 
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(std::span<const TclObject> tokens, TclObject& result,
122  EmuTime::param time) override;
123  [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
124  } keyMatrixUpCmd;
125 
126  struct KeyMatrixDownCmd final : RecordedCommand {
127  KeyMatrixDownCmd(CommandController& commandController,
128  StateChangeDistributor& stateChangeDistributor,
129  Scheduler& scheduler);
130  void execute(std::span<const TclObject> tokens, TclObject& result,
131  EmuTime::param time) override;
132  [[nodiscard]] std::string help(std::span<const TclObject> 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  [[nodiscard]] 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(std::span<const TclObject> tokens, TclObject& result,
150  EmuTime::param time) override;
151  [[nodiscard]] std::string help(std::span<const TclObject> 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  private:
158  std::string text_utf8;
159  unsigned last;
160  byte lockKeysMask;
161  bool releaseLast;
162  byte oldLocksOn;
163 
164  bool releaseBeforePress;
165  int typingFrequency;
166  } keyTypeCmd;
167 
168  struct Msxcode2UnicodeCmd final : public Command {
169  Msxcode2UnicodeCmd(CommandController& commandController);
170  void execute(std::span<const TclObject> tokens, TclObject& result) override;
171  [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
172  } msxcode2UnicodeCmd;
173 
174  struct Unicode2MsxcodeCmd final : public Command {
175  Unicode2MsxcodeCmd(CommandController& commandController);
176  void execute(std::span<const TclObject> tokens, TclObject& result) override;
177  [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
178  } unicode2MsxcodeCmd;
179 
180  class CapsLockAligner final : private EventListener, private Schedulable {
181  public:
182  CapsLockAligner(EventDistributor& eventDistributor,
183  Scheduler& scheduler);
184  ~CapsLockAligner();
185 
186  private:
187  // EventListener
188  int signalEvent(const Event& event) noexcept override;
189 
190  // Schedulable
191  void executeUntil(EmuTime::param time) override;
192 
193  void alignCapsLock(EmuTime::param time);
194 
195  private:
196  EventDistributor& eventDistributor;
197 
198  enum CapsLockAlignerStateType {
199  MUST_ALIGN_CAPSLOCK, MUST_DISTRIBUTE_KEY_RELEASE, IDLE
200  } state;
201  } capsLockAligner;
202 
203  KeyboardSettings keyboardSettings;
204 
205  class MsxKeyEventQueue final : public Schedulable {
206  public:
207  MsxKeyEventQueue(Scheduler& scheduler, Interpreter& interp);
208  void process_asap(EmuTime::param time,
209  const Event& event);
210  void clear();
211  template<typename Archive>
212  void serialize(Archive& ar, unsigned version);
213  private:
214  // Schedulable
215  void executeUntil(EmuTime::param time) override;
216  private:
217  std::deque<Event> eventQueue;
218  Interpreter& interp;
219  } msxKeyEventQueue;
220 
221  struct KeybDebuggable final : SimpleDebuggable {
222  explicit KeybDebuggable(MSXMotherBoard& motherBoard);
223  [[nodiscard]] byte read(unsigned address) override;
224  void write(unsigned address, byte value) override;
225  } keybDebuggable;
226 
227  UnicodeKeymap unicodeKeymap;
228  unsigned dynKeymap[MAX_KEYSYM];
229 
231  byte cmdKeyMatrix [KeyMatrixPosition::NUM_ROWS];
233  byte typeKeyMatrix [KeyMatrixPosition::NUM_ROWS];
235  byte userKeyMatrix[KeyMatrixPosition::NUM_ROWS];
237  byte hostKeyMatrix[KeyMatrixPosition::NUM_ROWS];
239  mutable byte keyMatrix[KeyMatrixPosition::NUM_ROWS];
240 
241  byte msxModifiers;
242 
244  const bool hasKeypad;
248  const bool blockRow11;
250  const bool keyGhosting;
252  const bool keyGhostingSGCprotected;
256  const byte modifierIsLock;
257  mutable bool keysChanged;
262  byte locksOn;
263 };
265 
266 } // namespace openmsx
267 
268 #endif
A position (row, column) in a keyboard matrix.
static constexpr unsigned NUM_ROWS
Rows are in the range [0..NUM_ROWS).
static constexpr int MAX_KEYSYM
Definition: Keyboard.hh:39
void transferHostKeyMatrix(const Keyboard &source)
Definition: Keyboard.cc:433
void serialize(Archive &ar, unsigned version)
Definition: Keyboard.cc:1618
const byte * getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition: Keyboard.cc:418
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:299
Commands that directly influence the MSX state should send and events so that they can be recorded by...
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:34
Schedulable(const Schedulable &)=delete
bool pendingSyncPoint() const
Definition: Schedulable.cc:38
virtual byte read(unsigned address, EmuTime::param time)
virtual void write(unsigned address, byte value, EmuTime::param time)
Base class for all external MSX state changing events.
Definition: StateChange.hh:20
KeyCode
Constants that identify keys and key modifiers.
Definition: Keys.hh:26
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
constexpr auto IDLE
Definition: WD2793.cc:40