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 "MSXEventListener.hh"
7#include "UnicodeKeymap.hh"
8
9#include "Event.hh"
10#include "EventListener.hh"
11#include "RecordedCommand.hh"
12#include "Schedulable.hh"
13#include "SimpleDebuggable.hh"
14#include "serialize_meta.hh"
15
16#include <array>
17#include <cstdint>
18#include <deque>
19#include <span>
20#include <string_view>
21#include <vector>
22
23namespace openmsx {
24
25class MSXMotherBoard;
26class Scheduler;
27class CommandController;
28class DeviceConfig;
29class EventDistributor;
30class MSXEventDistributor;
31class StateChangeDistributor;
32class StateChange;
33class TclObject;
34class Interpreter;
35
44
45class Keyboard final : private MSXEventListener, private StateChangeListener
46 , private Schedulable
47{
48public:
49 static constexpr int MAX_KEYSYM = 0x150;
50 enum class Matrix { MSX, SVI, CVJOY, SEGA, NUM };
51
62 Keyboard(MSXMotherBoard& motherBoard, Scheduler& scheduler,
63 CommandController& commandController,
64 EventDistributor& eventDistributor,
65 MSXEventDistributor& msxEventDistributor,
66 StateChangeDistributor& stateChangeDistributor,
67 Matrix matrix, const DeviceConfig& config);
68
69 ~Keyboard();
70
71 [[nodiscard]] const MsxChar2Unicode& getMsxChar2Unicode() const;
72
75 [[nodiscard]] std::span<const uint8_t, KeyMatrixPosition::NUM_ROWS> getKeys() const;
76
77 void transferHostKeyMatrix(const Keyboard& source);
78 void setFocus(bool newFocus, EmuTime::param time);
79
80 template<typename Archive>
81 void serialize(Archive& ar, unsigned version);
82
83private:
84 // MSXEventListener
85 void signalMSXEvent(const Event& event,
86 EmuTime::param time) noexcept override;
87 // StateChangeListener
88 void signalStateChange(const StateChange& event) override;
89 void stopReplay(EmuTime::param time) noexcept override;
90
91 // Schedulable
92 void executeUntil(EmuTime::param time) override;
93
94 void syncHostKeyMatrix(EmuTime::param time);
95 void pressKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
96 void releaseKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
97 void changeKeyMatrixEvent (EmuTime::param time, uint8_t row, uint8_t newValue);
98
99 void processCapslockEvent(EmuTime::param time, bool down);
100 void processCodeKanaChange(EmuTime::param time, bool down);
101 void processGraphChange(EmuTime::param time, bool down);
102 void processKeypadEnterKey(EmuTime::param time, bool down);
103 void processSdlKey(EmuTime::param time, SDLKey key);
104 bool processQueuedEvent(const Event& event, EmuTime::param time);
105 bool processKeyEvent(EmuTime::param time, bool down, const KeyEvent& keyEvent);
106 void updateKeyMatrix(EmuTime::param time, bool down, KeyMatrixPosition pos);
107 void processCmd(Interpreter& interp, std::span<const TclObject> tokens, bool up);
108 bool pressUnicodeByUser(
109 EmuTime::param time, UnicodeKeymap::KeyInfo keyInfo, unsigned unicode,
110 bool down);
111 uint8_t pressAscii(unsigned unicode, bool down);
112 void pressLockKeys(uint8_t lockKeysMask, bool down);
113 [[nodiscard]] bool commonKeys(unsigned unicode1, unsigned unicode2) const;
114 void debug(const char* format, ...) const;
115
120 uint8_t needsLockToggle(const UnicodeKeymap::KeyInfo& keyInfo) const;
121
122private:
123 CommandController& commandController;
124 MSXEventDistributor& msxEventDistributor;
125 StateChangeDistributor& stateChangeDistributor;
126
127 std::vector<KeyCodeMsxMapping> keyCodeTab;
128 std::vector<ScanCodeMsxMapping> scanCodeTab;
129
131
132 struct KeyMatrixUpCmd final : RecordedCommand {
133 KeyMatrixUpCmd(CommandController& commandController,
134 StateChangeDistributor& stateChangeDistributor,
135 Scheduler& scheduler);
136 void execute(std::span<const TclObject> tokens, TclObject& result,
137 EmuTime::param time) override;
138 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
139 } keyMatrixUpCmd;
140
141 struct KeyMatrixDownCmd final : RecordedCommand {
142 KeyMatrixDownCmd(CommandController& commandController,
143 StateChangeDistributor& stateChangeDistributor,
144 Scheduler& scheduler);
145 void execute(std::span<const TclObject> tokens, TclObject& result,
146 EmuTime::param time) override;
147 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
148 } keyMatrixDownCmd;
149
150 class KeyInserter final : public RecordedCommand, public Schedulable {
151 public:
152 KeyInserter(CommandController& commandController,
153 StateChangeDistributor& stateChangeDistributor,
154 Scheduler& scheduler);
155 [[nodiscard]] bool isActive() const { return pendingSyncPoint(); }
156 template<typename Archive>
157 void serialize(Archive& ar, unsigned version);
158
159 private:
160 void type(std::string_view str);
161 void reschedule(EmuTime::param time);
162
163 // Command
164 void execute(std::span<const TclObject> tokens, TclObject& result,
165 EmuTime::param time) override;
166 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
167 void tabCompletion(std::vector<std::string>& tokens) const override;
168
169 // Schedulable
170 void executeUntil(EmuTime::param time) override;
171
172 private:
173 std::string text_utf8;
174 unsigned last = 0;
175 uint8_t lockKeysMask = 0;
176 bool releaseLast = false;
177 uint8_t oldLocksOn = 0;
178
179 bool releaseBeforePress = false;
180 int typingFrequency = 15;
181 } keyTypeCmd;
182
183 struct Msxcode2UnicodeCmd final : public Command {
184 explicit Msxcode2UnicodeCmd(CommandController& commandController);
185 void execute(std::span<const TclObject> tokens, TclObject& result) override;
186 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
187 } msxcode2UnicodeCmd;
188
189 struct Unicode2MsxcodeCmd final : public Command {
190 explicit Unicode2MsxcodeCmd(CommandController& commandController);
191 void execute(std::span<const TclObject> tokens, TclObject& result) override;
192 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
193 } unicode2MsxcodeCmd;
194
195 class CapsLockAligner final : private EventListener, private Schedulable {
196 public:
197 CapsLockAligner(EventDistributor& eventDistributor,
198 Scheduler& scheduler);
199 ~CapsLockAligner();
200
201 private:
202 // EventListener
203 bool signalEvent(const Event& event) override;
204
205 // Schedulable
206 void executeUntil(EmuTime::param time) override;
207
208 void alignCapsLock(EmuTime::param time);
209
210 private:
211 EventDistributor& eventDistributor;
212
213 enum CapsLockAlignerStateType {
214 MUST_ALIGN_CAPSLOCK, MUST_DISTRIBUTE_KEY_RELEASE, IDLE
215 } state = IDLE;
216 } capsLockAligner;
217
218 KeyboardSettings keyboardSettings;
219
220 class MsxKeyEventQueue final : public Schedulable {
221 public:
222 MsxKeyEventQueue(Scheduler& scheduler, Interpreter& interp);
223 void process_asap(EmuTime::param time,
224 const Event& event);
225 void clear();
226 template<typename Archive>
227 void serialize(Archive& ar, unsigned version);
228 private:
229 // Schedulable
230 void executeUntil(EmuTime::param time) override;
231 private:
232 std::deque<Event> eventQueue;
233 Interpreter& interp;
234 } msxKeyEventQueue;
235
236 struct KeybDebuggable final : SimpleDebuggable {
237 explicit KeybDebuggable(MSXMotherBoard& motherBoard);
238 [[nodiscard]] uint8_t read(unsigned address) override;
239 void write(unsigned address, uint8_t value) override;
240 } keybDebuggable;
241
242 UnicodeKeymap unicodeKeymap;
243 // Remembers the last unicode for a key-press-keycode. To be used later
244 // on the corresponding key-release, because those don't have unicode info.
245 std::vector<std::pair<SDL_Keycode, uint32_t>> lastUnicodeForKeycode; // sorted on SDL_keycode
246
248 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> cmdKeyMatrix;
250 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> typeKeyMatrix;
252 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> userKeyMatrix;
254 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> hostKeyMatrix;
256 mutable std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> keyMatrix;
257
258 uint8_t msxModifiers = 0xff;
259
261 const bool hasKeypad;
265 const bool blockRow11;
267 const bool keyGhosting;
269 const bool keyGhostingSGCprotected;
273 const uint8_t modifierIsLock;
274 mutable bool keysChanged = false;
279 uint8_t locksOn = 0;
280
281 bool focus = true;
282};
284
285} // namespace openmsx
286
287#endif
A position (row, column) in a keyboard matrix.
static constexpr int MAX_KEYSYM
Definition Keyboard.hh:49
void transferHostKeyMatrix(const Keyboard &source)
Definition Keyboard.cc:828
void serialize(Archive &ar, unsigned version)
Definition Keyboard.cc:2040
void setFocus(bool newFocus, EmuTime::param time)
Definition Keyboard.cc:850
std::span< const uint8_t, KeyMatrixPosition::NUM_ROWS > getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition Keyboard.cc:813
const MsxChar2Unicode & getMsxChar2Unicode() const
Definition Keyboard.cc:748
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:11
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:445
#define SERIALIZE_CLASS_VERSION(CLASS, VERSION)
KeyMatrixPosition msx
Definition Keyboard.hh:38
KeyMatrixPosition msx
Definition Keyboard.hh:42