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
43
44class Keyboard final : private MSXEventListener, private StateChangeListener
45 , private Schedulable
46{
47public:
48 static constexpr int MAX_KEYSYM = 0x150;
50
61 Keyboard(MSXMotherBoard& motherBoard, Scheduler& scheduler,
62 CommandController& commandController,
63 EventDistributor& eventDistributor,
64 MSXEventDistributor& msxEventDistributor,
65 StateChangeDistributor& stateChangeDistributor,
66 MatrixType matrix, const DeviceConfig& config);
67
68 ~Keyboard();
69
70 [[nodiscard]] const MsxChar2Unicode& getMsxChar2Unicode() const;
71
74 [[nodiscard]] std::span<const uint8_t, KeyMatrixPosition::NUM_ROWS> getKeys() const;
75
76 void transferHostKeyMatrix(const Keyboard& source);
77
78 template<typename Archive>
79 void serialize(Archive& ar, unsigned version);
80
81private:
82 // MSXEventListener
83 void signalMSXEvent(const Event& event,
84 EmuTime::param time) noexcept override;
85 // StateChangeListener
86 void signalStateChange(const StateChange& event) override;
87 void stopReplay(EmuTime::param time) noexcept override;
88
89 // Schedulable
90 void executeUntil(EmuTime::param time) override;
91
92 void pressKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
93 void releaseKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
94 void changeKeyMatrixEvent (EmuTime::param time, uint8_t row, uint8_t newValue);
95
96 void processCapslockEvent(EmuTime::param time, bool down);
97 void processCodeKanaChange(EmuTime::param time, bool down);
98 void processGraphChange(EmuTime::param time, bool down);
99 void processKeypadEnterKey(EmuTime::param time, bool down);
100 void processSdlKey(EmuTime::param time, SDLKey key);
101 bool processQueuedEvent(const Event& event, EmuTime::param time);
102 bool processKeyEvent(EmuTime::param time, bool down, const KeyEvent& keyEvent);
103 void updateKeyMatrix(EmuTime::param time, bool down, KeyMatrixPosition pos);
104 void processCmd(Interpreter& interp, std::span<const TclObject> tokens, bool up);
105 bool pressUnicodeByUser(
106 EmuTime::param time, UnicodeKeymap::KeyInfo keyInfo, unsigned unicode,
107 bool down);
108 uint8_t pressAscii(unsigned unicode, bool down);
109 void pressLockKeys(uint8_t lockKeysMask, bool down);
110 bool commonKeys(unsigned unicode1, unsigned unicode2);
111 void debug(const char* format, ...);
112
117 uint8_t needsLockToggle(const UnicodeKeymap::KeyInfo& keyInfo) const;
118
119private:
120 CommandController& commandController;
121 MSXEventDistributor& msxEventDistributor;
122 StateChangeDistributor& stateChangeDistributor;
123
124 std::vector<KeyCodeMsxMapping> keyCodeTab;
125 std::vector<ScanCodeMsxMapping> scanCodeTab;
126
127 const std::array<KeyMatrixPosition, UnicodeKeymap::KeyInfo::NUM_MODIFIERS>& modifierPos;
128
129 struct KeyMatrixUpCmd final : RecordedCommand {
130 KeyMatrixUpCmd(CommandController& commandController,
131 StateChangeDistributor& stateChangeDistributor,
132 Scheduler& scheduler);
133 void execute(std::span<const TclObject> tokens, TclObject& result,
134 EmuTime::param time) override;
135 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
136 } keyMatrixUpCmd;
137
138 struct KeyMatrixDownCmd final : RecordedCommand {
139 KeyMatrixDownCmd(CommandController& commandController,
140 StateChangeDistributor& stateChangeDistributor,
141 Scheduler& scheduler);
142 void execute(std::span<const TclObject> tokens, TclObject& result,
143 EmuTime::param time) override;
144 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
145 } keyMatrixDownCmd;
146
147 class KeyInserter final : public RecordedCommand, public Schedulable {
148 public:
149 KeyInserter(CommandController& commandController,
150 StateChangeDistributor& stateChangeDistributor,
151 Scheduler& scheduler);
152 [[nodiscard]] bool isActive() const { return pendingSyncPoint(); }
153 template<typename Archive>
154 void serialize(Archive& ar, unsigned version);
155
156 private:
157 void type(std::string_view str);
158 void reschedule(EmuTime::param time);
159
160 // Command
161 void execute(std::span<const TclObject> tokens, TclObject& result,
162 EmuTime::param time) override;
163 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
164 void tabCompletion(std::vector<std::string>& tokens) const override;
165
166 // Schedulable
167 void executeUntil(EmuTime::param time) override;
168
169 private:
170 std::string text_utf8;
171 unsigned last = 0;
172 uint8_t lockKeysMask = 0;
173 bool releaseLast = false;
174 uint8_t oldLocksOn = 0;
175
176 bool releaseBeforePress = false;
177 int typingFrequency = 15;
178 } keyTypeCmd;
179
180 struct Msxcode2UnicodeCmd final : public Command {
181 Msxcode2UnicodeCmd(CommandController& commandController);
182 void execute(std::span<const TclObject> tokens, TclObject& result) override;
183 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
184 } msxcode2UnicodeCmd;
185
186 struct Unicode2MsxcodeCmd final : public Command {
187 Unicode2MsxcodeCmd(CommandController& commandController);
188 void execute(std::span<const TclObject> tokens, TclObject& result) override;
189 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
190 } unicode2MsxcodeCmd;
191
192 class CapsLockAligner final : private EventListener, private Schedulable {
193 public:
194 CapsLockAligner(EventDistributor& eventDistributor,
195 Scheduler& scheduler);
196 ~CapsLockAligner();
197
198 private:
199 // EventListener
200 int signalEvent(const Event& event) override;
201
202 // Schedulable
203 void executeUntil(EmuTime::param time) override;
204
205 void alignCapsLock(EmuTime::param time);
206
207 private:
208 EventDistributor& eventDistributor;
209
210 enum CapsLockAlignerStateType {
211 MUST_ALIGN_CAPSLOCK, MUST_DISTRIBUTE_KEY_RELEASE, IDLE
212 } state = IDLE;
213 } capsLockAligner;
214
215 KeyboardSettings keyboardSettings;
216
217 class MsxKeyEventQueue final : public Schedulable {
218 public:
219 MsxKeyEventQueue(Scheduler& scheduler, Interpreter& interp);
220 void process_asap(EmuTime::param time,
221 const Event& event);
222 void clear();
223 template<typename Archive>
224 void serialize(Archive& ar, unsigned version);
225 private:
226 // Schedulable
227 void executeUntil(EmuTime::param time) override;
228 private:
229 std::deque<Event> eventQueue;
230 Interpreter& interp;
231 } msxKeyEventQueue;
232
233 struct KeybDebuggable final : SimpleDebuggable {
234 explicit KeybDebuggable(MSXMotherBoard& motherBoard);
235 [[nodiscard]] uint8_t read(unsigned address) override;
236 void write(unsigned address, uint8_t value) override;
237 } keybDebuggable;
238
239 UnicodeKeymap unicodeKeymap;
240 // Remembers the last unicode for a key-press-keycode. To be used later
241 // on the corresponding key-release, because those don't have unicode info.
242 std::vector<std::pair<SDL_Keycode, uint32_t>> lastUnicodeForKeycode; // sorted on SDL_keycode
243
245 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> cmdKeyMatrix;
247 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> typeKeyMatrix;
249 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> userKeyMatrix;
251 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> hostKeyMatrix;
253 mutable std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> keyMatrix;
254
255 uint8_t msxModifiers = 0xff;
256
258 const bool hasKeypad;
262 const bool blockRow11;
264 const bool keyGhosting;
266 const bool keyGhostingSGCprotected;
270 const uint8_t modifierIsLock;
271 mutable bool keysChanged = false;
276 uint8_t locksOn = 0;
277};
279
280} // namespace openmsx
281
282#endif
A position (row, column) in a keyboard matrix.
static constexpr int MAX_KEYSYM
Definition Keyboard.hh:48
void transferHostKeyMatrix(const Keyboard &source)
Definition Keyboard.cc:816
void serialize(Archive &ar, unsigned version)
Definition Keyboard.cc:2011
std::span< const uint8_t, KeyMatrixPosition::NUM_ROWS > getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition Keyboard.cc:801
const MsxChar2Unicode & getMsxChar2Unicode() const
Definition Keyboard.cc:736
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.
bool pendingSyncPoint() const
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.
This file implemented 3 utility functions:
Definition Autofire.cc:9
void serialize(Archive &ar, T &t, unsigned version)
std::variant< KeyUpEvent, KeyDownEvent, MouseMotionEvent, MouseButtonUpEvent, MouseButtonDownEvent, MouseWheelEvent, JoystickAxisMotionEvent, JoystickHatEvent, JoystickButtonUpEvent, JoystickButtonDownEvent, OsdControlReleaseEvent, OsdControlPressEvent, WindowEvent, TextEvent, FileDropEvent, QuitEvent, FinishFrameEvent, CliCommandEvent, GroupEvent, BootEvent, FrameDrawnEvent, BreakEvent, SwitchRendererEvent, TakeReverseSnapshotEvent, AfterTimedEvent, MachineLoadedEvent, MachineActivatedEvent, MachineDeactivatedEvent, MidiInReaderEvent, MidiInWindowsEvent, MidiInCoreMidiEvent, MidiInCoreMidiVirtualEvent, MidiInALSAEvent, Rs232TesterEvent, Rs232NetEvent, ImGuiDelayedActionEvent, ImGuiActiveEvent > Event
Definition Event.hh:454
#define SERIALIZE_CLASS_VERSION(CLASS, VERSION)
KeyMatrixPosition msx
Definition Keyboard.hh:37
KeyMatrixPosition msx
Definition Keyboard.hh:41