27 {
"plain", QEvdevKeyboardMap::ModPlain, Qt::NoModifier },
28 {
"shift", QEvdevKeyboardMap::ModShift, Qt::ShiftModifier },
29 {
"altgr", QEvdevKeyboardMap::ModAltGr, Qt::AltModifier },
30 {
"control", QEvdevKeyboardMap::ModControl, Qt::ControlModifier },
31 {
"alt", QEvdevKeyboardMap::ModAlt, Qt::AltModifier },
32 {
"meta", QEvdevKeyboardMap::ModAlt, Qt::AltModifier },
33 {
"shiftl", QEvdevKeyboardMap::ModShiftL, Qt::ShiftModifier },
34 {
"shiftr", QEvdevKeyboardMap::ModShiftR, Qt::ShiftModifier },
35 {
"ctrll", QEvdevKeyboardMap::ModCtrlL, Qt::ControlModifier },
36 {
"ctrlr", QEvdevKeyboardMap::ModCtrlR, Qt::ControlModifier },
48 {
"space", Qt::Key_Space },
49 {
"exclam", Qt::Key_Exclam },
50 {
"quotedbl", Qt::Key_QuoteDbl },
51 {
"numbersign", Qt::Key_NumberSign },
52 {
"dollar", Qt::Key_Dollar },
53 {
"percent", Qt::Key_Percent },
54 {
"ampersand", Qt::Key_Ampersand },
55 {
"apostrophe", Qt::Key_Apostrophe },
56 {
"parenleft", Qt::Key_ParenLeft },
57 {
"parenright", Qt::Key_ParenRight },
58 {
"asterisk", Qt::Key_Asterisk },
59 {
"plus", Qt::Key_Plus },
60 {
"comma", Qt::Key_Comma },
61 {
"minus", Qt::Key_Minus },
62 {
"period", Qt::Key_Period },
63 {
"slash", Qt::Key_Slash },
64 {
"zero", Qt::Key_0 },
67 {
"three", Qt::Key_3 },
68 {
"four", Qt::Key_4 },
69 {
"five", Qt::Key_5 },
71 {
"seven", Qt::Key_7 },
72 {
"eight", Qt::Key_8 },
73 {
"nine", Qt::Key_9 },
74 {
"colon", Qt::Key_Colon },
75 {
"semicolon", Qt::Key_Semicolon },
76 {
"less", Qt::Key_Less },
77 {
"equal", Qt::Key_Equal },
78 {
"greater", Qt::Key_Greater },
79 {
"question", Qt::Key_Question },
81 {
"bracketleft", Qt::Key_BracketLeft },
82 {
"backslash", Qt::Key_Backslash },
83 {
"bracketright", Qt::Key_BracketRight },
84 {
"asciicircum", Qt::Key_AsciiCircum },
85 {
"underscore", Qt::Key_Underscore },
86 {
"grave", Qt::Key_QuoteLeft },
87 {
"braceleft", Qt::Key_BraceLeft },
88 {
"bar", Qt::Key_Bar },
89 {
"braceright", Qt::Key_BraceRight },
90 {
"asciitilde", Qt::Key_AsciiTilde },
91 {
"nobreakspace", Qt::Key_nobreakspace },
92 {
"exclamdown", Qt::Key_exclamdown },
93 {
"cent", Qt::Key_cent },
94 {
"sterling", Qt::Key_sterling },
95 {
"currency", Qt::Key_currency },
96 {
"yen", Qt::Key_yen },
97 {
"brokenbar", Qt::Key_brokenbar },
98 {
"section", Qt::Key_section },
99 {
"diaeresis", Qt::Key_diaeresis },
100 {
"copyright", Qt::Key_copyright },
101 {
"ordfeminine", Qt::Key_ordfeminine },
102 {
"guillemotleft", Qt::Key_guillemotleft },
103 {
"notsign", Qt::Key_notsign },
104 {
"hyphen", Qt::Key_hyphen },
105 {
"registered", Qt::Key_registered },
106 {
"macron", Qt::Key_macron },
107 {
"degree", Qt::Key_degree },
108 {
"plusminus", Qt::Key_plusminus },
109 {
"twosuperior", Qt::Key_twosuperior },
110 {
"threesuperior", Qt::Key_threesuperior },
111 {
"acute", Qt::Key_acute },
112 {
"micro", Qt::Key_micro },
113 {
"mu", Qt::Key_micro },
114 {
"paragraph", Qt::Key_paragraph },
115 {
"periodcentered", Qt::Key_periodcentered },
116 {
"cedilla", Qt::Key_cedilla },
117 {
"onesuperior", Qt::Key_onesuperior },
118 {
"masculine", Qt::Key_masculine },
119 {
"guillemotright", Qt::Key_guillemotright },
120 {
"onequarter", Qt::Key_onequarter },
121 {
"onehalf", Qt::Key_onehalf },
122 {
"threequarters", Qt::Key_threequarters },
123 {
"questiondown", Qt::Key_questiondown },
124 {
"Agrave", Qt::Key_Agrave },
125 {
"Aacute", Qt::Key_Aacute },
126 {
"Acircumflex", Qt::Key_Acircumflex },
127 {
"Atilde", Qt::Key_Atilde },
128 {
"Adiaeresis", Qt::Key_Adiaeresis },
129 {
"Aring", Qt::Key_Aring },
130 {
"AE", Qt::Key_AE },
131 {
"Ccedilla", Qt::Key_Ccedilla },
132 {
"Egrave", Qt::Key_Egrave },
133 {
"Eacute", Qt::Key_Eacute },
134 {
"Ecircumflex", Qt::Key_Ecircumflex },
135 {
"Ediaeresis", Qt::Key_Ediaeresis },
136 {
"Igrave", Qt::Key_Igrave },
137 {
"Iacute", Qt::Key_Iacute },
138 {
"Icircumflex", Qt::Key_Icircumflex },
139 {
"Idiaeresis", Qt::Key_Idiaeresis },
140 {
"ETH", Qt::Key_ETH },
141 {
"Ntilde", Qt::Key_Ntilde },
142 {
"Ograve", Qt::Key_Ograve },
143 {
"Oacute", Qt::Key_Oacute },
144 {
"Ocircumflex", Qt::Key_Ocircumflex },
145 {
"Otilde", Qt::Key_Otilde },
146 {
"Odiaeresis", Qt::Key_Odiaeresis },
147 {
"multiply", Qt::Key_multiply },
148 {
"Ooblique", Qt::Key_Ooblique },
149 {
"Ugrave", Qt::Key_Ugrave },
150 {
"Uacute", Qt::Key_Uacute },
151 {
"Ucircumflex", Qt::Key_Ucircumflex },
152 {
"Udiaeresis", Qt::Key_Udiaeresis },
153 {
"Yacute", Qt::Key_Yacute },
154 {
"THORN", Qt::Key_THORN },
155 {
"ssharp", Qt::Key_ssharp },
159 {
"acircumflex", 0xe2 },
161 {
"adiaeresis", 0xe4 },
164 {
"ccedilla", 0xe7 },
167 {
"ecircumflex", 0xea },
168 {
"ediaeresis", 0xeb },
171 {
"icircumflex", 0xee },
172 {
"idiaeresis", 0xef },
177 {
"ocircumflex", 0xf4 },
179 {
"odiaeresis", 0xf6 },
180 {
"division", Qt::Key_division },
184 {
"ucircumflex", 0xfb },
185 {
"udiaeresis", 0xfc },
188 {
"ydiaeresis", Qt::Key_ydiaeresis },
190 {
"F1", Qt::Key_F1 },
191 {
"F2", Qt::Key_F2 },
192 {
"F3", Qt::Key_F3 },
193 {
"F4", Qt::Key_F4 },
194 {
"F5", Qt::Key_F5 },
195 {
"F6", Qt::Key_F6 },
196 {
"F7", Qt::Key_F7 },
197 {
"F8", Qt::Key_F8 },
198 {
"F9", Qt::Key_F9 },
199 {
"F10", Qt::Key_F10 },
200 {
"F11", Qt::Key_F11 },
201 {
"F12", Qt::Key_F12 },
202 {
"F13", Qt::Key_F13 },
203 {
"F14", Qt::Key_F14 },
204 {
"F15", Qt::Key_F15 },
205 {
"F16", Qt::Key_F16 },
206 {
"F17", Qt::Key_F17 },
207 {
"F18", Qt::Key_F18 },
208 {
"F19", Qt::Key_F19 },
209 {
"F20", Qt::Key_F20 },
210 {
"F21", Qt::Key_F21 },
211 {
"F22", Qt::Key_F22 },
212 {
"F23", Qt::Key_F23 },
213 {
"F24", Qt::Key_F24 },
214 {
"F25", Qt::Key_F25 },
215 {
"F26", Qt::Key_F26 },
216 {
"F27", Qt::Key_F27 },
217 {
"F28", Qt::Key_F28 },
218 {
"F29", Qt::Key_F29 },
219 {
"F30", Qt::Key_F30 },
220 {
"F31", Qt::Key_F31 },
221 {
"F32", Qt::Key_F32 },
222 {
"F33", Qt::Key_F33 },
223 {
"F34", Qt::Key_F34 },
224 {
"F35", Qt::Key_F35 },
226 {
"BackSpace", Qt::Key_Backspace },
227 {
"Tab", Qt::Key_Tab },
228 {
"Escape", Qt::Key_Escape },
229 {
"Delete", Qt::Key_Backspace },
230 {
"Return", Qt::Key_Return },
231 {
"Break", Qt::Key_unknown },
232 {
"Caps_Lock", Qt::Key_CapsLock },
233 {
"Num_Lock", Qt::Key_NumLock },
234 {
"Scroll_Lock", Qt::Key_ScrollLock },
235 {
"Caps_On", Qt::Key_CapsLock },
236 {
"Compose", Qt::Key_Multi_key },
237 {
"Bare_Num_Lock", Qt::Key_NumLock },
238 {
"Find", Qt::Key_Home },
239 {
"Insert", Qt::Key_Insert },
240 {
"Remove", Qt::Key_Delete },
241 {
"Select", Qt::Key_End },
242 {
"Prior", Qt::Key_PageUp },
243 {
"Next", Qt::Key_PageDown },
244 {
"Help", Qt::Key_Help },
245 {
"Pause", Qt::Key_Pause },
246 {
"VolumeDown", Qt::Key_VolumeDown },
247 {
"VolumeUp", Qt::Key_VolumeUp },
248 {
"MediaTogglePlayPause", Qt::Key_MediaTogglePlayPause },
249 {
"MediaPlay", Qt::Key_MediaPlay },
250 {
"MediaPause", Qt::Key_MediaPause },
251 {
"MediaStop", Qt::Key_MediaStop },
252 {
"MediaNext", Qt::Key_MediaNext },
253 {
"MediaPrevious", Qt::Key_MediaPrevious },
254 {
"AudioForward", Qt::Key_AudioForward },
255 {
"AudioRewind", Qt::Key_AudioRewind },
256 {
"Camera", Qt::Key_Camera },
257 {
"CameraFocus", Qt::Key_CameraFocus },
259 {
"Call", Qt::Key_Call },
260 {
"Hangup", Qt::Key_Hangup },
261 {
"ToggleCallHangup", Qt::Key_ToggleCallHangup },
262 {
"VoiceDial" , Qt::Key_VoiceDial },
263 {
"LastNumberRedial", Qt::Key_LastNumberRedial },
265 {
"KP_0", Qt::Key_0 | Qt::KeypadModifier },
266 {
"KP_1", Qt::Key_1 | Qt::KeypadModifier },
267 {
"KP_2", Qt::Key_2 | Qt::KeypadModifier },
268 {
"KP_3", Qt::Key_3 | Qt::KeypadModifier },
269 {
"KP_4", Qt::Key_4 | Qt::KeypadModifier },
270 {
"KP_5", Qt::Key_5 | Qt::KeypadModifier },
271 {
"KP_6", Qt::Key_6 | Qt::KeypadModifier },
272 {
"KP_7", Qt::Key_7 | Qt::KeypadModifier },
273 {
"KP_8", Qt::Key_8 | Qt::KeypadModifier },
274 {
"KP_9", Qt::Key_9 | Qt::KeypadModifier },
275 {
"KP_Add", Qt::Key_Plus | Qt::KeypadModifier },
276 {
"KP_Subtract", Qt::Key_Minus | Qt::KeypadModifier },
277 {
"KP_Multiply", Qt::Key_Asterisk | Qt::KeypadModifier },
278 {
"KP_Divide", Qt::Key_Slash | Qt::KeypadModifier },
279 {
"KP_Enter", Qt::Key_Enter | Qt::KeypadModifier },
280 {
"KP_Comma", Qt::Key_Comma | Qt::KeypadModifier },
281 {
"KP_Period", Qt::Key_Period | Qt::KeypadModifier },
282 {
"KP_MinPlus", Qt::Key_plusminus | Qt::KeypadModifier },
284 {
"dead_grave", Qt::Key_Dead_Grave },
285 {
"dead_acute", Qt::Key_Dead_Acute },
286 {
"dead_circumflex", Qt::Key_Dead_Circumflex },
287 {
"dead_tilde", Qt::Key_Dead_Tilde },
288 {
"dead_diaeresis", Qt::Key_Dead_Diaeresis },
289 {
"dead_cedilla", Qt::Key_Dead_Cedilla },
291 {
"Down", Qt::Key_Down },
292 {
"Left", Qt::Key_Left },
293 {
"Right", Qt::Key_Right },
294 {
"Up", Qt::Key_Up },
295 {
"Shift", Qt::Key_Shift },
296 {
"AltGr", Qt::Key_AltGr },
297 {
"Control", Qt::Key_Control },
298 {
"Alt", Qt::Key_Alt },
299 {
"ShiftL", Qt::Key_Shift },
300 {
"ShiftR", Qt::Key_Shift },
301 {
"CtrlL", Qt::Key_Control },
302 {
"CtrlR", Qt::Key_Control },
554bool KeymapParser::parseKmap(QFile *f)
559 auto codec = QStringDecoder(QStringDecoder::Latin1);
561 for (
int i = 0; i <= 256; ++i)
564 while (!f->atEnd() && !f->error()) {
565 line = f->readLine();
568 QList<QByteArray> tokens = tokenize(line);
570 if (tokens.isEmpty())
573 if (tokens[0] ==
"keymaps") {
576 if (tokens.count() > 1) {
577 const QByteArrayList tokenList = tokens[1].split(
',');
578 for (
const QByteArray §ion : tokenList) {
579 int dashpos = section.indexOf(
'-');
582 int end = section.mid(dashpos + 1).toInt();
585 start = section.left(dashpos).toInt();
587 if (start <= end && start >=0 && end <= 256) {
588 for (
int i = start; i <= end; ++i) {
596 std::sort(keymaps.begin(), keymaps.end());
601 else if (tokens[0] ==
"alt_is_meta") {
604 else if (tokens[0] ==
"include") {
605 if (tokens.count() == 2) {
606 QString incname = QString::fromLocal8Bit(tokens[1]);
608 QList<QDir> searchpath;
611 if (!incname.endsWith(QLatin1String(
".kmap")) && !incname.endsWith(QLatin1String(
".inc")))
612 incname.append(QLatin1String(
".inc"));
616 if (d.cdUp() && d.cd(QLatin1String(
"include")))
618 searchpath << QDir::current();
620 for (
const QDir &path : std::as_const(searchpath)) {
621 QFile f2(path.filePath(incname));
623 if (f2.open(QIODevice::ReadOnly)) {
633 parseWarning(
"include doesn't have exactly one argument");
635 else if (tokens[0] ==
"charset") {
636 if (tokens.count() == 2) {
637 codec = QStringDecoder(tokens[1]);
638 if (!codec.isValid()) {
640 codec = QStringDecoder(QStringDecoder::Latin1);
643 parseWarning(
"codec doesn't have exactly one argument");
645 else if (tokens[0] ==
"strings") {
648 else if (tokens[0] ==
"compose") {
649 if (tokens.count() == 5 && tokens[3] ==
"to") {
650 QEvdevKeyboardMap::Composing c = { 0xffff, 0xffff, 0xffff };
652 if (!parseCompose(tokens[1], codec, c.first))
654 if (!parseCompose(tokens[2], codec, c.second))
656 if (!parseCompose(tokens[4], codec, c.result))
657 parseWarning(
"could not parse resulting compose symbol");
659 if (c.first != 0xffff && c.second != 0xffff && c.result != 0xffff) {
666 int kcpos = tokens.indexOf(
"keycode");
668 if (kcpos >= 0 && kcpos < (tokens.count()-3) && tokens[kcpos+2] ==
"=") {
669 quint16 keycode = tokens[kcpos+1].toInt();
671 if (keycode <= 0 || keycode > 0x2ff ) {
676 bool line_modifiers = (kcpos > 0);
678 quint8 modifiers = 0;
679 for (
int i = 0; i < kcpos; ++i) {
681 if (!parseModifier(tokens[i], mod)) {
688 int kccount = tokens.count() - kcpos - 3;
690 if (line_modifiers && kccount > 1) {
691 parseWarning(
"line has modifiers, but more than one keycode");
696 for (
int i = 0; i < (line_modifiers ? 1 : kccount); ++i) {
698 modifiers = keymaps[i];
704 if (!parseSymbol(tokens[i + kcpos + 3], unicode, qtcode, flags, special)) {
705 parseWarning((QByteArray(
"symbol could not be parsed: ") + tokens[i + kcpos + 3]).constData());
709 if (qtcode == Qt::Key_unknown && unicode == 0xffff)
712 if (!line_modifiers && kccount == 1) {
713 if ((unicode >=
'A' && unicode <=
'Z') || (unicode >=
'a' && unicode <=
'z')) {
714 quint16 other_unicode = (unicode >=
'A' && unicode <=
'Z') ? unicode -
'A' +
'a' : unicode -
'a' +
'A';
715 quint16 lower_unicode = (unicode >=
'A' && unicode <=
'Z') ? unicode -
'A' +
'a' : unicode;
719 updateMapping(keycode, QEvdevKeyboardMap::ModPlain, unicode, qtcode, flags, 0);
721 updateMapping(keycode, QEvdevKeyboardMap::ModShift, other_unicode, qtcode, flags, 0);
723 updateMapping(keycode, QEvdevKeyboardMap::ModAltGr, unicode, qtcode, flags, 0);
724 updateMapping(keycode, QEvdevKeyboardMap::ModAltGr | QEvdevKeyboardMap::ModShift, other_unicode, qtcode, flags, 0);
726 updateMapping(keycode, QEvdevKeyboardMap::ModControl, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
727 updateMapping(keycode, QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModShift, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
728 updateMapping(keycode, QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModAltGr, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
729 updateMapping(keycode, QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModAltGr | QEvdevKeyboardMap::ModShift, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
731 updateMapping(keycode, QEvdevKeyboardMap::ModAlt, unicode, qtcode | Qt::AltModifier, flags, 0);
732 updateMapping(keycode, QEvdevKeyboardMap::ModAlt | QEvdevKeyboardMap::ModShift, unicode, qtcode | Qt::AltModifier, flags, 0);
733 updateMapping(keycode, QEvdevKeyboardMap::ModAlt | QEvdevKeyboardMap::ModAltGr, unicode, qtcode | Qt::AltModifier, flags, 0);
734 updateMapping(keycode, QEvdevKeyboardMap::ModAlt | QEvdevKeyboardMap::ModAltGr | QEvdevKeyboardMap::ModShift, unicode, qtcode | Qt::AltModifier, flags, 0);
736 updateMapping(keycode, QEvdevKeyboardMap::ModAlt | QEvdevKeyboardMap::ModControl, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
737 updateMapping(keycode, QEvdevKeyboardMap::ModAlt | QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModShift, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
738 updateMapping(keycode, QEvdevKeyboardMap::ModAlt | QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModAltGr, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
739 updateMapping(keycode, QEvdevKeyboardMap::ModAlt | QEvdevKeyboardMap::ModControl | QEvdevKeyboardMap::ModAltGr | QEvdevKeyboardMap::ModShift, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
747 updateMapping(keycode, QEvdevKeyboardMap::ModPlain, unicode, qtcode, flags, special);
752 updateMapping(keycode, modifiers, unicode, qtcode, flags, special);
758 std::sort(m_keymap.begin(), m_keymap.end());
759 return !m_keymap.isEmpty();