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 {
37 public:
39 
50  Keyboard(MSXMotherBoard& motherBoard, Scheduler& scheduler,
51  CommandController& commandController,
52  EventDistributor& eventDistributor,
53  MSXEventDistributor& msxEventDistributor,
54  StateChangeDistributor& stateChangeDistributor,
55  MatrixType matrix, const DeviceConfig& config);
56 
57  ~Keyboard();
58 
61  const byte* getKeys() const;
62 
63  void transferHostKeyMatrix(const Keyboard& source);
64 
65  template<typename Archive>
66  void serialize(Archive& ar, unsigned version);
67 
68 private:
69  // MSXEventListener
70  void signalMSXEvent(const std::shared_ptr<const Event>& event,
71  EmuTime::param time) override;
72  // StateChangeListener
73  void signalStateChange(const std::shared_ptr<StateChange>& event) override;
74  void stopReplay(EmuTime::param time) override;
75 
76  void pressKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
77  void releaseKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
78  void changeKeyMatrixEvent (EmuTime::param time, byte row, byte newValue);
79 
80  void processCapslockEvent(EmuTime::param time, bool down);
81  void processCodeKanaChange(EmuTime::param time, bool down);
82  void processGraphChange(EmuTime::param time, bool down);
83  void processKeypadEnterKey(EmuTime::param time, bool down);
84  void processSdlKey(EmuTime::param time, bool down, Keys::KeyCode key);
85  bool processQueuedEvent(const Event& event, EmuTime::param time);
86  bool processKeyEvent(EmuTime::param time, bool down, const KeyEvent& keyEvent);
87  void updateKeyMatrix(EmuTime::param time, bool down, KeyMatrixPosition pos);
88  void processCmd(Interpreter& interp, span<const TclObject> tokens, bool up);
89  bool pressUnicodeByUser(
90  EmuTime::param time, UnicodeKeymap::KeyInfo keyInfo, unsigned unicode,
91  bool down);
92  int pressAscii(unsigned unicode, bool down);
93  void pressLockKeys(byte lockKeysMask, bool down);
94  bool commonKeys(unsigned unicode1, unsigned unicode2);
95  void debug(const char* format, ...);
96 
101  byte needsLockToggle(const UnicodeKeymap::KeyInfo& keyInfo) const;
102 
103  CommandController& commandController;
104  MSXEventDistributor& msxEventDistributor;
105  StateChangeDistributor& stateChangeDistributor;
106 
107  static constexpr int MAX_KEYSYM = 0x150;
108  static const KeyMatrixPosition keyTabs[][MAX_KEYSYM];
109  const KeyMatrixPosition* keyTab;
110 
111  const std::array<KeyMatrixPosition, UnicodeKeymap::KeyInfo::NUM_MODIFIERS>& modifierPos;
112 
113  struct KeyMatrixUpCmd final : RecordedCommand {
114  KeyMatrixUpCmd(CommandController& commandController,
115  StateChangeDistributor& stateChangeDistributor,
116  Scheduler& scheduler);
117  void execute(span<const TclObject> tokens, TclObject& result,
118  EmuTime::param time) override;
119  std::string help(const std::vector<std::string>& tokens) const override;
120  } keyMatrixUpCmd;
121 
122  struct KeyMatrixDownCmd final : RecordedCommand {
123  KeyMatrixDownCmd(CommandController& commandController,
124  StateChangeDistributor& stateChangeDistributor,
125  Scheduler& scheduler);
126  void execute(span<const TclObject> tokens, TclObject& result,
127  EmuTime::param time) override;
128  std::string help(const std::vector<std::string>& tokens) const override;
129  } keyMatrixDownCmd;
130 
131  class KeyInserter final : public RecordedCommand, public Schedulable {
132  public:
133  KeyInserter(CommandController& commandController,
134  StateChangeDistributor& stateChangeDistributor,
135  Scheduler& scheduler);
136  bool isActive() const { return pendingSyncPoint(); }
137  template<typename Archive>
138  void serialize(Archive& ar, unsigned version);
139 
140  private:
141  void type(std::string_view str);
142  void reschedule(EmuTime::param time);
143 
144  // Command
145  void execute(span<const TclObject> tokens, TclObject& result,
146  EmuTime::param time) override;
147  std::string help(const std::vector<std::string>& tokens) const override;
148  void tabCompletion(std::vector<std::string>& tokens) const override;
149 
150  // Schedulable
151  void executeUntil(EmuTime::param time) override;
152 
153  std::string text_utf8;
154  unsigned last;
155  byte lockKeysMask;
156  bool releaseLast;
157  byte oldLocksOn;
158 
159  bool releaseBeforePress;
160  int typingFrequency;
161  } keyTypeCmd;
162 
163  class CapsLockAligner final : private EventListener, private Schedulable {
164  public:
165  CapsLockAligner(EventDistributor& eventDistributor,
166  Scheduler& scheduler);
167  ~CapsLockAligner();
168 
169  private:
170  // EventListener
171  int signalEvent(const std::shared_ptr<const Event>& event) override;
172 
173  // Schedulable
174  void executeUntil(EmuTime::param time) override;
175 
176  void alignCapsLock(EmuTime::param time);
177 
178  EventDistributor& eventDistributor;
179 
180  enum CapsLockAlignerStateType {
181  MUST_ALIGN_CAPSLOCK, MUST_DISTRIBUTE_KEY_RELEASE, IDLE
182  } state;
183  } capsLockAligner;
184 
185  KeyboardSettings keyboardSettings;
186 
187  class MsxKeyEventQueue final : public Schedulable {
188  public:
189  MsxKeyEventQueue(Scheduler& scheduler, Interpreter& interp);
190  void process_asap(EmuTime::param time,
191  const std::shared_ptr<const Event>& event);
192  void clear();
193  template<typename Archive>
194  void serialize(Archive& ar, unsigned version);
195  private:
196  // Schedulable
197  void executeUntil(EmuTime::param time) override;
198  std::deque<std::shared_ptr<const Event>> eventQueue;
199  Interpreter& interp;
200  } msxKeyEventQueue;
201 
202  struct KeybDebuggable final : SimpleDebuggable {
203  explicit KeybDebuggable(MSXMotherBoard& motherBoard);
204  byte read(unsigned address) override;
205  void write(unsigned address, byte value) override;
206  } keybDebuggable;
207 
208  UnicodeKeymap unicodeKeymap;
209  unsigned dynKeymap[MAX_KEYSYM];
210 
212  byte cmdKeyMatrix [KeyMatrixPosition::NUM_ROWS];
214  byte typeKeyMatrix [KeyMatrixPosition::NUM_ROWS];
216  byte userKeyMatrix[KeyMatrixPosition::NUM_ROWS];
218  byte hostKeyMatrix[KeyMatrixPosition::NUM_ROWS];
220  mutable byte keyMatrix[KeyMatrixPosition::NUM_ROWS];
221 
222  byte msxmodifiers;
223 
225  const bool hasKeypad;
229  const bool blockRow11;
231  const bool keyGhosting;
233  const bool keyGhostingSGCprotected;
237  const byte modifierIsLock;
238  mutable bool keysChanged;
243  byte locksOn;
244 };
246 
247 } // namespace openmsx
248 
249 #endif
const byte * getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition: Keyboard.cc:213
A position (row, column) in a keyboard matrix.
Definition: span.hh:34
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
constexpr auto IDLE
Definition: WD2793.cc:40
Commands that directly influence the MSX state should send and events so that they can be recorded by...
KeyCode
Constants that identify keys and key modifiers.
Definition: Keys.hh:25
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:33
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
void serialize(Archive &ar, unsigned version)
Definition: Keyboard.cc:1305
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:100
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
static constexpr unsigned NUM_ROWS
Rows are in the range [0..NUM_ROWS).
void transferHostKeyMatrix(const Keyboard &source)
Definition: Keyboard.cc:228
void format(SectorAccessibleDisk &disk, bool dos1)
Format the given disk (= a single partition).