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"
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 <array>
15#include <cstdint>
16#include <deque>
17#include <memory>
18#include <span>
19#include <string_view>
20#include <vector>
21
22namespace openmsx {
23
24class MSXMotherBoard;
25class Scheduler;
26class CommandController;
27class DeviceConfig;
28class EventDistributor;
29class MSXEventDistributor;
30class StateChangeDistributor;
31class StateChange;
32class TclObject;
33class Interpreter;
34
35class Keyboard final : private MSXEventListener, private StateChangeListener
36 , private Schedulable
37{
38public:
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
61 [[nodiscard]] const MsxChar2Unicode& getMsxChar2Unicode() const;
62
65 [[nodiscard]] std::span<const uint8_t, KeyMatrixPosition::NUM_ROWS> getKeys() const;
66
67 void transferHostKeyMatrix(const Keyboard& source);
68
69 template<typename Archive>
70 void serialize(Archive& ar, unsigned version);
71
72private:
73 // MSXEventListener
74 void signalMSXEvent(const Event& event,
75 EmuTime::param time) noexcept override;
76 // StateChangeListener
77 void signalStateChange(const StateChange& event) override;
78 void stopReplay(EmuTime::param time) noexcept override;
79
80 // Schedulable
81 void executeUntil(EmuTime::param time) override;
82
83 void pressKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
84 void releaseKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
85 void changeKeyMatrixEvent (EmuTime::param time, uint8_t row, uint8_t newValue);
86
87 void processCapslockEvent(EmuTime::param time, bool down);
88 void processCodeKanaChange(EmuTime::param time, bool down);
89 void processGraphChange(EmuTime::param time, bool down);
90 void processKeypadEnterKey(EmuTime::param time, bool down);
91 void processSdlKey(EmuTime::param time, bool down, Keys::KeyCode key);
92 bool processQueuedEvent(const Event& event, EmuTime::param time);
93 bool processKeyEvent(EmuTime::param time, bool down, const KeyEvent& keyEvent);
94 void updateKeyMatrix(EmuTime::param time, bool down, KeyMatrixPosition pos);
95 void processCmd(Interpreter& interp, std::span<const TclObject> tokens, bool up);
96 bool pressUnicodeByUser(
97 EmuTime::param time, UnicodeKeymap::KeyInfo keyInfo, unsigned unicode,
98 bool down);
99 uint8_t pressAscii(unsigned unicode, bool down);
100 void pressLockKeys(uint8_t lockKeysMask, bool down);
101 bool commonKeys(unsigned unicode1, unsigned unicode2);
102 void debug(const char* format, ...);
103
108 uint8_t needsLockToggle(const UnicodeKeymap::KeyInfo& keyInfo) const;
109
110private:
111 CommandController& commandController;
112 MSXEventDistributor& msxEventDistributor;
113 StateChangeDistributor& stateChangeDistributor;
114
115 std::span<const KeyMatrixPosition, MAX_KEYSYM> keyTab;
116
117 const std::array<KeyMatrixPosition, UnicodeKeymap::KeyInfo::NUM_MODIFIERS>& modifierPos;
118
119 struct KeyMatrixUpCmd final : RecordedCommand {
120 KeyMatrixUpCmd(CommandController& commandController,
121 StateChangeDistributor& stateChangeDistributor,
122 Scheduler& scheduler);
123 void execute(std::span<const TclObject> tokens, TclObject& result,
124 EmuTime::param time) override;
125 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
126 } keyMatrixUpCmd;
127
128 struct KeyMatrixDownCmd final : RecordedCommand {
129 KeyMatrixDownCmd(CommandController& commandController,
130 StateChangeDistributor& stateChangeDistributor,
131 Scheduler& scheduler);
132 void execute(std::span<const TclObject> tokens, TclObject& result,
133 EmuTime::param time) override;
134 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
135 } keyMatrixDownCmd;
136
137 class KeyInserter final : public RecordedCommand, public Schedulable {
138 public:
139 KeyInserter(CommandController& commandController,
140 StateChangeDistributor& stateChangeDistributor,
141 Scheduler& scheduler);
142 [[nodiscard]] bool isActive() const { return pendingSyncPoint(); }
143 template<typename Archive>
144 void serialize(Archive& ar, unsigned version);
145
146 private:
147 void type(std::string_view str);
148 void reschedule(EmuTime::param time);
149
150 // Command
151 void execute(std::span<const TclObject> tokens, TclObject& result,
152 EmuTime::param time) override;
153 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
154 void tabCompletion(std::vector<std::string>& tokens) const override;
155
156 // Schedulable
157 void executeUntil(EmuTime::param time) override;
158
159 private:
160 std::string text_utf8;
161 unsigned last = 0;
162 uint8_t lockKeysMask = 0;
163 bool releaseLast = false;
164 uint8_t oldLocksOn = 0;
165
166 bool releaseBeforePress = false;
167 int typingFrequency = 15;
168 } keyTypeCmd;
169
170 struct Msxcode2UnicodeCmd final : public Command {
171 Msxcode2UnicodeCmd(CommandController& commandController);
172 void execute(std::span<const TclObject> tokens, TclObject& result) override;
173 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
174 } msxcode2UnicodeCmd;
175
176 struct Unicode2MsxcodeCmd final : public Command {
177 Unicode2MsxcodeCmd(CommandController& commandController);
178 void execute(std::span<const TclObject> tokens, TclObject& result) override;
179 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
180 } unicode2MsxcodeCmd;
181
182 class CapsLockAligner final : private EventListener, private Schedulable {
183 public:
184 CapsLockAligner(EventDistributor& eventDistributor,
185 Scheduler& scheduler);
186 ~CapsLockAligner();
187
188 private:
189 // EventListener
190 int signalEvent(const Event& event) override;
191
192 // Schedulable
193 void executeUntil(EmuTime::param time) override;
194
195 void alignCapsLock(EmuTime::param time);
196
197 private:
198 EventDistributor& eventDistributor;
199
200 enum CapsLockAlignerStateType {
201 MUST_ALIGN_CAPSLOCK, MUST_DISTRIBUTE_KEY_RELEASE, IDLE
202 } state = IDLE;
203 } capsLockAligner;
204
205 KeyboardSettings keyboardSettings;
206
207 class MsxKeyEventQueue final : public Schedulable {
208 public:
209 MsxKeyEventQueue(Scheduler& scheduler, Interpreter& interp);
210 void process_asap(EmuTime::param time,
211 const Event& event);
212 void clear();
213 template<typename Archive>
214 void serialize(Archive& ar, unsigned version);
215 private:
216 // Schedulable
217 void executeUntil(EmuTime::param time) override;
218 private:
219 std::deque<Event> eventQueue;
220 Interpreter& interp;
221 } msxKeyEventQueue;
222
223 struct KeybDebuggable final : SimpleDebuggable {
224 explicit KeybDebuggable(MSXMotherBoard& motherBoard);
225 [[nodiscard]] uint8_t read(unsigned address) override;
226 void write(unsigned address, uint8_t value) override;
227 } keybDebuggable;
228
229 UnicodeKeymap unicodeKeymap;
230 std::array<unsigned, MAX_KEYSYM> dynKeymap;
231
233 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> cmdKeyMatrix;
235 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> typeKeyMatrix;
237 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> userKeyMatrix;
239 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> hostKeyMatrix;
241 mutable std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> keyMatrix;
242
243 uint8_t msxModifiers = 0xff;
244
246 const bool hasKeypad;
250 const bool blockRow11;
252 const bool keyGhosting;
254 const bool keyGhostingSGCprotected;
258 const uint8_t modifierIsLock;
259 mutable bool keysChanged = false;
264 uint8_t locksOn = 0;
265};
267
268} // namespace openmsx
269
270#endif
A position (row, column) in a keyboard matrix.
static constexpr int MAX_KEYSYM
Definition: Keyboard.hh:39
void transferHostKeyMatrix(const Keyboard &source)
Definition: Keyboard.cc:435
void serialize(Archive &ar, unsigned version)
Definition: Keyboard.cc:1614
std::span< const uint8_t, KeyMatrixPosition::NUM_ROWS > getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition: Keyboard.cc:420
const MsxChar2Unicode & getMsxChar2Unicode() const
Definition: Keyboard.cc:355
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)