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:
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 std::shared_ptr<const Event>& event,
73  EmuTime::param time) noexcept override;
74  // StateChangeListener
75  void signalStateChange(const std::shared_ptr<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, 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(span<const TclObject> tokens, TclObject& result,
122  EmuTime::param time) override;
123  [[nodiscard]] 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  [[nodiscard]] 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  [[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(span<const TclObject> tokens, TclObject& result,
150  EmuTime::param time) override;
151  [[nodiscard]] 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  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  class CapsLockAligner final : private EventListener, private Schedulable {
169  public:
170  CapsLockAligner(EventDistributor& eventDistributor,
171  Scheduler& scheduler);
172  ~CapsLockAligner();
173 
174  private:
175  // EventListener
176  int signalEvent(const std::shared_ptr<const Event>& event) noexcept override;
177 
178  // Schedulable
179  void executeUntil(EmuTime::param time) override;
180 
181  void alignCapsLock(EmuTime::param time);
182 
183  private:
184  EventDistributor& eventDistributor;
185 
186  enum CapsLockAlignerStateType {
187  MUST_ALIGN_CAPSLOCK, MUST_DISTRIBUTE_KEY_RELEASE, IDLE
188  } state;
189  } capsLockAligner;
190 
191  KeyboardSettings keyboardSettings;
192 
193  class MsxKeyEventQueue final : public Schedulable {
194  public:
195  MsxKeyEventQueue(Scheduler& scheduler, Interpreter& interp);
196  void process_asap(EmuTime::param time,
197  const std::shared_ptr<const Event>& event);
198  void clear();
199  template<typename Archive>
200  void serialize(Archive& ar, unsigned version);
201  private:
202  // Schedulable
203  void executeUntil(EmuTime::param time) override;
204  private:
205  std::deque<std::shared_ptr<const Event>> eventQueue;
206  Interpreter& interp;
207  } msxKeyEventQueue;
208 
209  struct KeybDebuggable final : SimpleDebuggable {
210  explicit KeybDebuggable(MSXMotherBoard& motherBoard);
211  [[nodiscard]] byte read(unsigned address) override;
212  void write(unsigned address, byte value) override;
213  } keybDebuggable;
214 
215  UnicodeKeymap unicodeKeymap;
216  unsigned dynKeymap[MAX_KEYSYM];
217 
219  byte cmdKeyMatrix [KeyMatrixPosition::NUM_ROWS];
221  byte typeKeyMatrix [KeyMatrixPosition::NUM_ROWS];
223  byte userKeyMatrix[KeyMatrixPosition::NUM_ROWS];
225  byte hostKeyMatrix[KeyMatrixPosition::NUM_ROWS];
227  mutable byte keyMatrix[KeyMatrixPosition::NUM_ROWS];
228 
229  byte msxModifiers;
230 
232  const bool hasKeypad;
236  const bool blockRow11;
238  const bool keyGhosting;
240  const bool keyGhostingSGCprotected;
244  const byte modifierIsLock;
245  mutable bool keysChanged;
250  byte locksOn;
251 };
253 
254 } // namespace openmsx
255 
256 #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:377
void serialize(Archive &ar, unsigned version)
Definition: Keyboard.cc:1459
const byte * getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition: Keyboard.cc:362
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:248
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)
Definition: span.hh:126
KeyCode
Constants that identify keys and key modifiers.
Definition: Keys.hh:26
This file implemented 3 utility functions:
Definition: Autofire.cc:5
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
constexpr auto IDLE
Definition: WD2793.cc:40