openMSX
UnicodeKeymap.hh
Go to the documentation of this file.
1#ifndef UNICODEKEYMAP_HH
2#define UNICODEKEYMAP_HH
3
4#include "CommandException.hh"
5#include "MsxChar2Unicode.hh"
6
7#include "narrow.hh"
8#include "stl.hh"
9
10#include <array>
11#include <cassert>
12#include <cstdint>
13#include <optional>
14#include <string_view>
15#include <vector>
16
17namespace openmsx {
18
21class KeyMatrixPosition final {
22 static constexpr unsigned INVALID = 0xFF;
23
24public:
26 static constexpr unsigned NUM_ROWS = 16;
28 static constexpr unsigned NUM_COLS = 8;
30 static constexpr unsigned NUM_ROWCOL = 1 << 7;
31
35 constexpr KeyMatrixPosition() = default;
36
40 explicit constexpr KeyMatrixPosition(uint8_t rowCol_)
41 : KeyMatrixPosition(rowCol_ >> 4, rowCol_ & 0x0F)
42 {
43 }
44
47 constexpr KeyMatrixPosition(unsigned row, unsigned col)
48 : rowCol(narrow<uint8_t>((row << 3) | col))
49 {
50 assert(row < NUM_ROWS);
51 assert(col < NUM_COLS);
52 assert(isValid());
53 }
54
57 [[nodiscard]] constexpr bool isValid() const {
58 return rowCol != INVALID;
59 }
60
64 [[nodiscard]] constexpr uint8_t getRow() const {
65 assert(isValid());
66 return rowCol >> 3;
67 }
68
72 [[nodiscard]] constexpr uint8_t getColumn() const {
73 assert(isValid());
74 return rowCol & 0x07;
75 }
76
81 [[nodiscard]] constexpr uint8_t getRowCol() const {
82 assert(isValid());
83 return rowCol;
84 }
85
90 [[nodiscard]] constexpr uint8_t getMask() const {
91 assert(isValid());
92 return uint8_t(1 << getColumn());
93 }
94
95 [[nodiscard]] constexpr bool operator==(const KeyMatrixPosition&) const = default;
96
97private:
98 uint8_t rowCol = INVALID;
99};
100
102{
103public:
104 struct KeyInfo {
105 enum class Modifier { SHIFT, CTRL, GRAPH, CAPS, CODE, NUM };
106 // Modifier masks:
107 static constexpr uint8_t SHIFT_MASK = 1 << to_underlying(Modifier::SHIFT);
108 static constexpr uint8_t CTRL_MASK = 1 << to_underlying(Modifier::CTRL);
109 static constexpr uint8_t GRAPH_MASK = 1 << to_underlying(Modifier::GRAPH);
110 static constexpr uint8_t CAPS_MASK = 1 << to_underlying(Modifier::CAPS);
111 static constexpr uint8_t CODE_MASK = 1 << to_underlying(Modifier::CODE);
112
113 constexpr KeyInfo() = default;
114 constexpr KeyInfo(KeyMatrixPosition pos_, uint8_t modMask_)
115 : pos(pos_), modMask(modMask_)
116 {
117 assert(pos.isValid());
118 }
119 [[nodiscard]] constexpr bool isValid() const {
120 return pos.isValid();
121 }
123 uint8_t modMask = 0;
124 };
125
126 explicit UnicodeKeymap(std::string_view keyboardType);
127
128 [[nodiscard]] KeyInfo get(unsigned unicode) const;
129 [[nodiscard]] KeyInfo getDeadKey(unsigned n) const;
130
137 [[nodiscard]] uint8_t getRelevantMods(const KeyInfo& keyInfo) const {
138 return relevantMods[keyInfo.pos.getRowCol()];
139 }
140
141 [[nodiscard]] const MsxChar2Unicode& getMsxChars() const {
142 if (!msxChars) throw CommandException("Missing MSX-Video-characterset file"); // TODO make this required for MSX/SVI machines
143 return *msxChars;
144 }
145
146private:
147 static constexpr unsigned NUM_DEAD_KEYS = 3;
148
149 void parseUnicodeKeyMapFile(std::string_view data);
150
151private:
152 struct Entry {
153 unsigned unicode;
154 KeyInfo keyInfo;
155 };
156 std::vector<Entry> mapData; // sorted on unicode
157
161 std::array<uint8_t, KeyMatrixPosition::NUM_ROWCOL> relevantMods;
162 std::array<KeyInfo, NUM_DEAD_KEYS> deadKeys;
163
164 std::optional<MsxChar2Unicode> msxChars; // TODO should this be required for MSX/SVI machines?
165};
166
167} // namespace openmsx
168
169#endif
A position (row, column) in a keyboard matrix.
constexpr uint8_t getColumn() const
Returns the matrix column.
constexpr KeyMatrixPosition(uint8_t rowCol_)
Creates a key matrix position from a uint8_t: the row is stored in the high nibble,...
constexpr bool isValid() const
Returns true iff this position is valid.
static constexpr unsigned NUM_ROWCOL
Combined row and column values are in the range [0..NUM_ROWCOL).
constexpr KeyMatrixPosition(unsigned row, unsigned col)
Creates a key matrix position with a given row and column.
constexpr uint8_t getRowCol() const
Returns the matrix row and column combined in a single uint8_t: the column is stored in the lower 3 b...
constexpr bool operator==(const KeyMatrixPosition &) const =default
constexpr KeyMatrixPosition()=default
Creates an invalid key matrix position, which can be used when a key does not exist on a particular k...
static constexpr unsigned NUM_COLS
Columns are in the range [0..NUM_COLS).
constexpr uint8_t getMask() const
Returns a mask with the bit corresponding to this position's column set, all other bits clear.
static constexpr unsigned NUM_ROWS
Rows are in the range [0..NUM_ROWS).
constexpr uint8_t getRow() const
Returns the matrix row.
KeyInfo getDeadKey(unsigned n) const
KeyInfo get(unsigned unicode) const
uint8_t getRelevantMods(const KeyInfo &keyInfo) const
Returns a mask in which a bit is set iff the corresponding modifier is relevant for the given key.
const MsxChar2Unicode & getMsxChars() const
This file implemented 3 utility functions:
Definition Autofire.cc:11
constexpr To narrow(From from) noexcept
Definition narrow.hh:37
constexpr auto to_underlying(E e) noexcept
Definition stl.hh:465
constexpr KeyInfo(KeyMatrixPosition pos_, uint8_t modMask_)
static constexpr uint8_t CAPS_MASK
constexpr KeyInfo()=default
constexpr bool isValid() const
static constexpr uint8_t SHIFT_MASK
static constexpr uint8_t GRAPH_MASK
static constexpr uint8_t CODE_MASK
static constexpr uint8_t CTRL_MASK