00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include <kbd.h>
00035 #include <io/console.h>
00036 #include <io/keycode.h>
00037 #include <bool.h>
00038 #include <layout.h>
00039
00040 static void layout_reset(void);
00041 static wchar_t layout_parse_ev(console_event_t *ev);
00042
00043 enum m_state {
00044 ms_start,
00045 ms_hacek,
00046 ms_carka
00047 };
00048
00049 static enum m_state mstate;
00050
00051 layout_op_t cz_op = {
00052 layout_reset,
00053 layout_parse_ev
00054 };
00055
00056 static wchar_t map_lcase[] = {
00057 [KC_Q] = 'q',
00058 [KC_W] = 'w',
00059 [KC_E] = 'e',
00060 [KC_R] = 'r',
00061 [KC_T] = 't',
00062 [KC_Y] = 'z',
00063 [KC_U] = 'u',
00064 [KC_I] = 'i',
00065 [KC_O] = 'o',
00066 [KC_P] = 'p',
00067
00068 [KC_A] = 'a',
00069 [KC_S] = 's',
00070 [KC_D] = 'd',
00071 [KC_F] = 'f',
00072 [KC_G] = 'g',
00073 [KC_H] = 'h',
00074 [KC_J] = 'j',
00075 [KC_K] = 'k',
00076 [KC_L] = 'l',
00077
00078 [KC_Z] = 'y',
00079 [KC_X] = 'x',
00080 [KC_C] = 'c',
00081 [KC_V] = 'v',
00082 [KC_B] = 'b',
00083 [KC_N] = 'n',
00084 [KC_M] = 'm',
00085 };
00086
00087 static wchar_t map_ucase[] = {
00088 [KC_Q] = 'Q',
00089 [KC_W] = 'W',
00090 [KC_E] = 'E',
00091 [KC_R] = 'R',
00092 [KC_T] = 'T',
00093 [KC_Y] = 'Z',
00094 [KC_U] = 'U',
00095 [KC_I] = 'I',
00096 [KC_O] = 'O',
00097 [KC_P] = 'P',
00098
00099 [KC_A] = 'A',
00100 [KC_S] = 'S',
00101 [KC_D] = 'D',
00102 [KC_F] = 'F',
00103 [KC_G] = 'G',
00104 [KC_H] = 'H',
00105 [KC_J] = 'J',
00106 [KC_K] = 'K',
00107 [KC_L] = 'L',
00108
00109 [KC_Z] = 'Y',
00110 [KC_X] = 'X',
00111 [KC_C] = 'C',
00112 [KC_V] = 'V',
00113 [KC_B] = 'B',
00114 [KC_N] = 'N',
00115 [KC_M] = 'M',
00116 };
00117
00118 static wchar_t map_not_shifted[] = {
00119 [KC_BACKTICK] = ';',
00120
00121 [KC_1] = '+',
00122
00123 [KC_MINUS] = '=',
00124
00125 [KC_RBRACKET] = ')',
00126
00127 [KC_QUOTE] = L'§',
00128
00129 [KC_COMMA] = ',',
00130 [KC_PERIOD] = '.',
00131 [KC_SLASH] = '-',
00132 };
00133
00134 static wchar_t map_shifted[] = {
00135 [KC_1] = '1',
00136 [KC_2] = '2',
00137 [KC_3] = '3',
00138 [KC_4] = '4',
00139 [KC_5] = '5',
00140 [KC_6] = '6',
00141 [KC_7] = '7',
00142 [KC_8] = '8',
00143 [KC_9] = '9',
00144 [KC_0] = '0',
00145
00146 [KC_MINUS] = '%',
00147
00148 [KC_LBRACKET] = '/',
00149 [KC_RBRACKET] = '(',
00150
00151 [KC_SEMICOLON] = '"',
00152 [KC_QUOTE] = '!',
00153 [KC_BACKSLASH] = '\'',
00154
00155 [KC_COMMA] = '?',
00156 [KC_PERIOD] = ':',
00157 [KC_SLASH] = '_',
00158 };
00159
00160 static wchar_t map_ns_nocaps[] = {
00161 [KC_2] = L'ě',
00162 [KC_3] = L'š',
00163 [KC_4] = L'č',
00164 [KC_5] = L'ř',
00165 [KC_6] = L'ž',
00166 [KC_7] = L'ý',
00167 [KC_8] = L'á',
00168 [KC_9] = L'í',
00169 [KC_0] = L'é',
00170
00171 [KC_LBRACKET] = L'ú',
00172 [KC_SEMICOLON] = L'ů'
00173 };
00174
00175 static wchar_t map_ns_caps[] = {
00176 [KC_2] = L'Ě',
00177 [KC_3] = L'Š',
00178 [KC_4] = L'Č',
00179 [KC_5] = L'Ř',
00180 [KC_6] = L'Ž',
00181 [KC_7] = L'Ý',
00182 [KC_8] = L'Á',
00183 [KC_9] = L'Í',
00184 [KC_0] = L'É',
00185
00186 [KC_LBRACKET] = L'Ú',
00187 [KC_SEMICOLON] = L'Ů'
00188 };
00189
00190 static wchar_t map_neutral[] = {
00191 [KC_BACKSPACE] = '\b',
00192 [KC_TAB] = '\t',
00193 [KC_ENTER] = '\n',
00194 [KC_SPACE] = ' ',
00195
00196 [KC_NSLASH] = '/',
00197 [KC_NTIMES] = '*',
00198 [KC_NMINUS] = '-',
00199 [KC_NPLUS] = '+',
00200 [KC_NENTER] = '\n'
00201 };
00202
00203 static wchar_t map_numeric[] = {
00204 [KC_N7] = '7',
00205 [KC_N8] = '8',
00206 [KC_N9] = '9',
00207 [KC_N4] = '4',
00208 [KC_N5] = '5',
00209 [KC_N6] = '6',
00210 [KC_N1] = '1',
00211 [KC_N2] = '2',
00212 [KC_N3] = '3',
00213
00214 [KC_N0] = '0',
00215 [KC_NPERIOD] = '.'
00216 };
00217
00218 static wchar_t map_hacek_lcase[] = {
00219 [KC_E] = L'ě',
00220 [KC_R] = L'ř',
00221 [KC_T] = L'ť',
00222 [KC_Y] = L'ž',
00223 [KC_U] = L'ů',
00224
00225 [KC_S] = L'š',
00226 [KC_D] = L'ď',
00227
00228 [KC_C] = L'č',
00229 [KC_N] = L'ň'
00230 };
00231
00232 static wchar_t map_hacek_ucase[] = {
00233 [KC_E] = L'Ě',
00234 [KC_R] = L'Ř',
00235 [KC_T] = L'Ť',
00236 [KC_Y] = L'Ž',
00237 [KC_U] = L'Ů',
00238
00239 [KC_S] = L'Š',
00240 [KC_D] = L'Ď',
00241
00242 [KC_C] = L'Č',
00243 [KC_N] = L'Ň'
00244 };
00245
00246 static wchar_t map_carka_lcase[] = {
00247 [KC_E] = L'é',
00248 [KC_U] = L'ú',
00249 [KC_I] = L'í',
00250 [KC_O] = L'ó',
00251
00252 [KC_A] = L'á',
00253
00254 [KC_Z] = L'ý',
00255 };
00256
00257 static wchar_t map_carka_ucase[] = {
00258 [KC_E] = L'É',
00259 [KC_U] = L'Ú',
00260 [KC_I] = L'Í',
00261 [KC_O] = L'Ó',
00262
00263 [KC_A] = L'Á',
00264
00265 [KC_Z] = L'Ý',
00266 };
00267
00268 static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
00269 {
00270 if (key >= map_length)
00271 return 0;
00272 return map[key];
00273 }
00274
00275 static wchar_t parse_ms_hacek(console_event_t *ev)
00276 {
00277 wchar_t c;
00278
00279 mstate = ms_start;
00280
00281
00282 if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
00283 return 0;
00284
00285 if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
00286 c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
00287 else
00288 c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
00289
00290 return c;
00291 }
00292
00293 static wchar_t parse_ms_carka(console_event_t *ev)
00294 {
00295 wchar_t c;
00296
00297 mstate = ms_start;
00298
00299
00300 if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
00301 return 0;
00302
00303 if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
00304 c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
00305 else
00306 c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
00307
00308 return c;
00309 }
00310
00311 static wchar_t parse_ms_start(console_event_t *ev)
00312 {
00313 wchar_t c;
00314
00315
00316 if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
00317 return 0;
00318
00319 if (ev->key == KC_EQUALS) {
00320 if ((ev->mods & KM_SHIFT) != 0)
00321 mstate = ms_hacek;
00322 else
00323 mstate = ms_carka;
00324
00325 return 0;
00326 }
00327
00328 c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
00329 if (c != 0)
00330 return c;
00331
00332 if ((ev->mods & KM_SHIFT) == 0) {
00333 if ((ev->mods & KM_CAPS_LOCK) != 0)
00334 c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
00335 else
00336 c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
00337
00338 if (c != 0)
00339 return c;
00340 }
00341
00342 if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
00343 c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
00344 else
00345 c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
00346
00347 if (c != 0)
00348 return c;
00349
00350 if ((ev->mods & KM_SHIFT) != 0)
00351 c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
00352 else
00353 c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
00354
00355 if (c != 0)
00356 return c;
00357
00358 if ((ev->mods & KM_NUM_LOCK) != 0)
00359 c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
00360 else
00361 c = 0;
00362
00363 return c;
00364 }
00365
00366 static bool key_is_mod(unsigned key)
00367 {
00368 switch (key) {
00369 case KC_LSHIFT:
00370 case KC_RSHIFT:
00371 case KC_LALT:
00372 case KC_RALT:
00373 case KC_LCTRL:
00374 case KC_RCTRL:
00375 return true;
00376 default:
00377 return false;
00378 }
00379 }
00380
00381 static void layout_reset(void)
00382 {
00383 mstate = ms_start;
00384 }
00385
00386 static wchar_t layout_parse_ev(console_event_t *ev)
00387 {
00388 if (ev->type != KEY_PRESS)
00389 return 0;
00390
00391 if (key_is_mod(ev->key))
00392 return 0;
00393
00394 switch (mstate) {
00395 case ms_start:
00396 return parse_ms_start(ev);
00397 case ms_hacek:
00398 return parse_ms_hacek(ev);
00399 case ms_carka:
00400 return parse_ms_carka(ev);
00401 }
00402
00403 return 0;
00404 }
00405