16using std::string_view;
22[[nodiscard]]
static constexpr std::optional<unsigned> parseHex(string_view str)
28 for (
const char c : str) {
30 if (
'0' <= c && c <=
'9') {
32 }
else if (
'A' <= c && c <=
'F') {
33 value += c -
'A' + 10;
34 }
else if (
'a' <= c && c <=
'f') {
35 value += c -
'a' + 10;
47[[nodiscard]]
static constexpr bool isSep(
char c)
57static constexpr void skipSep(string_view& str)
59 while (!str.empty()) {
60 const char c = str.front();
64 while (!str.empty() && str.front() !=
'\n') str.remove_prefix(1);
74[[nodiscard]]
static constexpr string_view nextToken(string_view& str)
77 const auto* tokenBegin = str.data();
78 while (!str.empty() && str.front() !=
'\n' && !isSep(str.front())) {
82 return {tokenBegin, size_t(str.data() - tokenBegin)};
89 tmpStrCat(
"unicodemaps/unicodemap.", keyboardType));
92 auto buf = file.
mmap();
93 parseUnicodeKeyMapFile(
94 string_view(std::bit_cast<const char*>(buf.data()), buf.size()));
98 if (!msxChars.has_value()) {
99 msxChars.emplace(
"MSXVID.TXT");
102 throw MSXException(
"Couldn't load unicode keymap file: ", filename);
108 auto m =
binary_find(mapData, unicode, {}, &Entry::unicode);
109 return m ? m->keyInfo :
KeyInfo();
114 assert(n < NUM_DEAD_KEYS);
118void UnicodeKeymap::parseUnicodeKeyMapFile(string_view data)
122 while (!data.empty()) {
123 if (data.front() ==
'\n') {
125 data.remove_prefix(1);
128 string_view token = nextToken(data);
134 if (token ==
"MSX-Video-Characterset:") {
135 auto vidFileName = nextToken(data);
136 if (vidFileName.empty()) {
137 throw MSXException(
"Missing filename for MSX-Video-Characterset");
139 msxChars.emplace(vidFileName);
144 unsigned unicode = 0;
145 unsigned deadKeyIndex = 0;
146 bool isDeadKey = token.starts_with(
"DEADKEY");
148 token.remove_prefix(strlen(
"DEADKEY"));
155 auto d = parseHex(token);
156 if (!d || *d > NUM_DEAD_KEYS) {
158 "Wrong deadkey number in keymap file. "
159 "It must be 1..", NUM_DEAD_KEYS);
161 deadKeyIndex = *d - 1;
164 auto u = parseHex(token);
165 if (!u || *u > 0x1FBFF) {
166 throw MSXException(
"Wrong unicode value in keymap file");
172 token = nextToken(data);
177 auto rowcol = parseHex(token);
178 if (!rowcol || *rowcol >= 0x100) {
180 (token.empty() ?
"Missing" :
"Wrong"),
181 " <ROW><COL> value in keymap file");
184 throw MSXException(
"Too high row value in keymap file");
187 throw MSXException(
"Too high column value in keymap file");
189 auto pos = KeyMatrixPosition(narrow_cast<uint8_t>(*rowcol));
194 token = nextToken(data);
197 }
else if (token ==
"SHIFT") {
199 }
else if (token ==
"CTRL") {
201 }
else if (token ==
"GRAPH") {
203 }
else if (token ==
"CAPSLOCK") {
205 }
else if (token ==
"CODE") {
209 "Invalid modifier \"", token,
"\" in keymap file");
216 "DEADKEY entry in keymap file cannot have modifiers");
218 deadKeys[deadKeyIndex] =
KeyInfo(pos, 0);
220 mapData.emplace_back(Entry{unicode,
KeyInfo(pos, modMask)});
222 relevantMods[pos.getRowCol()] |= modMask;
std::string resolve(std::string_view filename) const
std::span< const uint8_t > mmap()
Map file in memory.
static constexpr unsigned NUM_COLS
Columns are in the range [0..NUM_COLS).
static constexpr unsigned NUM_ROWS
Rows are in the range [0..NUM_ROWS).
KeyInfo getDeadKey(unsigned n) const
KeyInfo get(unsigned unicode) const
UnicodeKeymap(std::string_view keyboardType)
This file implemented 3 utility functions:
const FileContext & systemFileContext()
UnicodeKeymap::KeyInfo KeyInfo
constexpr void fill(ForwardRange &&range, const T &value)
constexpr void sort(RandomAccessRange &&range)
auto * binary_find(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
TemporaryString tmpStrCat(Ts &&... ts)
static constexpr uint8_t CAPS_MASK
static constexpr uint8_t SHIFT_MASK
static constexpr uint8_t GRAPH_MASK
static constexpr uint8_t CODE_MASK
static constexpr uint8_t CTRL_MASK