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 };
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
79 template<typename Archive>
80 void serialize(Archive& ar, unsigned version);
81
82private:
83 // MSXEventListener
84 void signalMSXEvent(const Event& event,
85 EmuTime::param time) noexcept override;
86 // StateChangeListener
87 void signalStateChange(const StateChange& event) override;
88 void stopReplay(EmuTime::param time) noexcept override;
89
90 // Schedulable
91 void executeUntil(EmuTime::param time) override;
92
93 void pressKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
94 void releaseKeyMatrixEvent(EmuTime::param time, KeyMatrixPosition pos);
95 void changeKeyMatrixEvent (EmuTime::param time, uint8_t row, uint8_t newValue);
96
97 void processCapslockEvent(EmuTime::param time, bool down);
98 void processCodeKanaChange(EmuTime::param time, bool down);
99 void processGraphChange(EmuTime::param time, bool down);
100 void processKeypadEnterKey(EmuTime::param time, bool down);
101 void processSdlKey(EmuTime::param time, SDLKey key);
102 bool processQueuedEvent(const Event& event, EmuTime::param time);
103 bool processKeyEvent(EmuTime::param time, bool down, const KeyEvent& keyEvent);
104 void updateKeyMatrix(EmuTime::param time, bool down, KeyMatrixPosition pos);
105 void processCmd(Interpreter& interp, std::span<const TclObject> tokens, bool up);
106 bool pressUnicodeByUser(
107 EmuTime::param time, UnicodeKeymap::KeyInfo keyInfo, unsigned unicode,
108 bool down);
109 uint8_t pressAscii(unsigned unicode, bool down);
110 void pressLockKeys(uint8_t lockKeysMask, bool down);
111 [[nodiscard]] bool commonKeys(unsigned unicode1, unsigned unicode2) const;
112 void debug(const char* format, ...) const;
113
118 uint8_t needsLockToggle(const UnicodeKeymap::KeyInfo& keyInfo) const;
119
120private:
121 CommandController& commandController;
122 MSXEventDistributor& msxEventDistributor;
123 StateChangeDistributor& stateChangeDistributor;
124
125 std::vector<KeyCodeMsxMapping> keyCodeTab;
126 std::vector<ScanCodeMsxMapping> scanCodeTab;
127
128 const std::array<KeyMatrixPosition, UnicodeKeymap::KeyInfo::NUM_MODIFIERS>& modifierPos;
129
130 struct KeyMatrixUpCmd final : RecordedCommand {
131 KeyMatrixUpCmd(CommandController& commandController,
132 StateChangeDistributor& stateChangeDistributor,
133 Scheduler& scheduler);
134 void execute(std::span<const TclObject> tokens, TclObject& result,
135 EmuTime::param time) override;
136 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
137 } keyMatrixUpCmd;
138
139 struct KeyMatrixDownCmd final : RecordedCommand {
140 KeyMatrixDownCmd(CommandController& commandController,
141 StateChangeDistributor& stateChangeDistributor,
142 Scheduler& scheduler);
143 void execute(std::span<const TclObject> tokens, TclObject& result,
144 EmuTime::param time) override;
145 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
146 } keyMatrixDownCmd;
147
148 class KeyInserter final : public RecordedCommand, public Schedulable {
149 public:
150 KeyInserter(CommandController& commandController,
151 StateChangeDistributor& stateChangeDistributor,
152 Scheduler& scheduler);
153 [[nodiscard]] bool isActive() const { return pendingSyncPoint(); }
154 template<typename Archive>
155 void serialize(Archive& ar, unsigned version);
156
157 private:
158 void type(std::string_view str);
159 void reschedule(EmuTime::param time);
160
161 // Command
162 void execute(std::span<const TclObject> tokens, TclObject& result,
163 EmuTime::param time) override;
164 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
165 void tabCompletion(std::vector<std::string>& tokens) const override;
166
167 // Schedulable
168 void executeUntil(EmuTime::param time) override;
169
170 private:
171 std::string text_utf8;
172 unsigned last = 0;
173 uint8_t lockKeysMask = 0;
174 bool releaseLast = false;
175 uint8_t oldLocksOn = 0;
176
177 bool releaseBeforePress = false;
178 int typingFrequency = 15;
179 } keyTypeCmd;
180
181 struct Msxcode2UnicodeCmd final : public Command {
182 explicit Msxcode2UnicodeCmd(CommandController& commandController);
183 void execute(std::span<const TclObject> tokens, TclObject& result) override;
184 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
185 } msxcode2UnicodeCmd;
186
187 struct Unicode2MsxcodeCmd final : public Command {
188 explicit Unicode2MsxcodeCmd(CommandController& commandController);
189 void execute(std::span<const TclObject> tokens, TclObject& result) override;
190 [[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
191 } unicode2MsxcodeCmd;
192
193 class CapsLockAligner final : private EventListener, private Schedulable {
194 public:
195 CapsLockAligner(EventDistributor& eventDistributor,
196 Scheduler& scheduler);
197 ~CapsLockAligner();
198
199 private:
200 // EventListener
201 int signalEvent(const Event& event) override;
202
203 // Schedulable
204 void executeUntil(EmuTime::param time) override;
205
206 void alignCapsLock(EmuTime::param time);
207
208 private:
209 EventDistributor& eventDistributor;
210
211 enum CapsLockAlignerStateType {
212 MUST_ALIGN_CAPSLOCK, MUST_DISTRIBUTE_KEY_RELEASE, IDLE
213 } state = IDLE;
214 } capsLockAligner;
215
216 KeyboardSettings keyboardSettings;
217
218 class MsxKeyEventQueue final : public Schedulable {
219 public:
220 MsxKeyEventQueue(Scheduler& scheduler, Interpreter& interp);
221 void process_asap(EmuTime::param time,
222 const Event& event);
223 void clear();
224 template<typename Archive>
225 void serialize(Archive& ar, unsigned version);
226 private:
227 // Schedulable
228 void executeUntil(EmuTime::param time) override;
229 private:
230 std::deque<Event> eventQueue;
231 Interpreter& interp;
232 } msxKeyEventQueue;
233
234 struct KeybDebuggable final : SimpleDebuggable {
235 explicit KeybDebuggable(MSXMotherBoard& motherBoard);
236 [[nodiscard]] uint8_t read(unsigned address) override;
237 void write(unsigned address, uint8_t value) override;
238 } keybDebuggable;
239
240 UnicodeKeymap unicodeKeymap;
241 // Remembers the last unicode for a key-press-keycode. To be used later
242 // on the corresponding key-release, because those don't have unicode info.
243 std::vector<std::pair<SDL_Keycode, uint32_t>> lastUnicodeForKeycode; // sorted on SDL_keycode
244
246 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> cmdKeyMatrix;
248 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> typeKeyMatrix;
250 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> userKeyMatrix;
252 std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> hostKeyMatrix;
254 mutable std::array<uint8_t, KeyMatrixPosition::NUM_ROWS> keyMatrix;
255
256 uint8_t msxModifiers = 0xff;
257
259 const bool hasKeypad;
263 const bool blockRow11;
265 const bool keyGhosting;
267 const bool keyGhostingSGCprotected;
271 const uint8_t modifierIsLock;
272 mutable bool keysChanged = false;
277 uint8_t locksOn = 0;
278};
280
281} // namespace openmsx
282
283#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:824
void serialize(Archive &ar, unsigned version)
Definition Keyboard.cc:2021
std::span< const uint8_t, KeyMatrixPosition::NUM_ROWS > getKeys() const
Returns a pointer to the current KeyBoard matrix.
Definition Keyboard.cc:809
const MsxChar2Unicode & getMsxChar2Unicode() const
Definition Keyboard.cc:744
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:446
#define SERIALIZE_CLASS_VERSION(CLASS, VERSION)
KeyMatrixPosition msx
Definition Keyboard.hh:38
KeyMatrixPosition msx
Definition Keyboard.hh:42