12 using std::string_view;
18 [[nodiscard]]
static constexpr std::optional<unsigned> parseHex(string_view str)
24 for (
const char c : str) {
26 if (
'0' <= c && c <=
'9') {
28 }
else if (
'A' <= c && c <=
'F') {
29 value += c -
'A' + 10;
30 }
else if (
'a' <= c && c <=
'f') {
31 value += c -
'a' + 10;
43 [[nodiscard]]
static constexpr
bool isSep(
char c)
53 static constexpr
void skipSep(string_view& str)
55 while (!str.empty()) {
56 const char c = str.front();
60 while (!str.empty() && str.front() !=
'\n') str.remove_prefix(1);
70 [[nodiscard]]
static constexpr string_view nextToken(string_view& str)
73 const auto* tokenBegin = str.data();
74 while (!str.empty() && str.front() !=
'\n' && !isSep(str.front())) {
78 return {tokenBegin, size_t(str.data() - tokenBegin)};
85 tmpStrCat(
"unicodemaps/unicodemap.", keyboardType));
88 auto buf = file.
mmap();
89 parseUnicodeKeymapfile(
90 string_view(
reinterpret_cast<const char*
>(buf.data()), buf.size()));
99 return ((it !=
end(mapdata)) && (it->unicode == unicode))
105 assert(n < NUM_DEAD_KEYS);
109 void UnicodeKeymap::parseUnicodeKeymapfile(string_view data)
111 memset(relevantMods, 0,
sizeof(relevantMods));
113 while (!data.empty()) {
114 if (data.front() ==
'\n') {
116 data.remove_prefix(1);
119 string_view token = nextToken(data);
125 if (token ==
"MSX-Video-Characterset:") {
126 auto vidFileName = nextToken(data);
127 if (vidFileName.empty()) {
128 throw MSXException(
"Missing filename for MSX-Video-Characterset");
130 msxChars.emplace(vidFileName);
135 unsigned unicode = 0;
136 unsigned deadKeyIndex = 0;
137 bool isDeadKey = token.starts_with(
"DEADKEY");
139 token.remove_prefix(strlen(
"DEADKEY"));
146 auto d = parseHex(token);
147 if (!d || *d > NUM_DEAD_KEYS) {
149 "Wrong deadkey number in keymap file. "
150 "It must be 1..", NUM_DEAD_KEYS);
152 deadKeyIndex = *d - 1;
155 auto u = parseHex(token);
156 if (!u || *u > 0x1FBFF) {
157 throw MSXException(
"Wrong unicode value in keymap file");
163 token = nextToken(data);
168 auto rowcol = parseHex(token);
169 if (!rowcol || *rowcol >= 0x100) {
171 (token.empty() ?
"Missing" :
"Wrong"),
172 " <ROW><COL> value in keymap file");
175 throw MSXException(
"Too high row value in keymap file");
178 throw MSXException(
"Too high column value in keymap file");
180 auto pos = KeyMatrixPosition(*rowcol);
185 token = nextToken(data);
188 }
else if (token ==
"SHIFT") {
190 }
else if (token ==
"CTRL") {
192 }
else if (token ==
"GRAPH") {
194 }
else if (token ==
"CAPSLOCK") {
196 }
else if (token ==
"CODE") {
200 "Invalid modifier \"", token,
"\" in keymap file");
207 "DEADKEY entry in keymap file cannot have modifiers");
209 deadKeys[deadKeyIndex] =
KeyInfo(pos, 0);
211 mapdata.emplace_back(Entry{unicode,
KeyInfo(pos, modmask)});
213 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 get(unsigned unicode) const
UnicodeKeymap(std::string_view keyboardType)
KeyInfo getDeadkey(unsigned n) const
This file implemented 3 utility functions:
const FileContext & systemFileContext()
constexpr const char *const filename
UnicodeKeymap::KeyInfo KeyInfo
constexpr void sort(RandomAccessRange &&range)
auto lower_bound(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
TemporaryString tmpStrCat(Ts &&... ts)
static constexpr byte CAPS_MASK
static constexpr byte CTRL_MASK
static constexpr byte GRAPH_MASK
static constexpr byte CODE_MASK
static constexpr byte SHIFT_MASK
constexpr auto end(const zstring_view &x)