~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to uspace/srv/kbd/layout/cz.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2009 Jiri Svoboda
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * - Redistributions of source code must retain the above copyright
 
10
 *   notice, this list of conditions and the following disclaimer.
 
11
 * - Redistributions in binary form must reproduce the above copyright
 
12
 *   notice, this list of conditions and the following disclaimer in the
 
13
 *   documentation and/or other materials provided with the distribution.
 
14
 * - The name of the author may not be used to endorse or promote products
 
15
 *   derived from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/** @addtogroup kbd
 
30
 * @brief Czech QWERTZ layout.
 
31
 * @{
 
32
 */
 
33
 
 
34
#include <kbd.h>
 
35
#include <io/console.h>
 
36
#include <io/keycode.h>
 
37
#include <bool.h>
 
38
#include <layout.h>
 
39
 
 
40
static void layout_reset(void);
 
41
static wchar_t layout_parse_ev(console_event_t *ev);
 
42
 
 
43
enum m_state {
 
44
        ms_start,
 
45
        ms_hacek,
 
46
        ms_carka
 
47
};
 
48
 
 
49
static enum m_state mstate;
 
50
 
 
51
layout_op_t cz_op = {
 
52
        layout_reset,
 
53
        layout_parse_ev
 
54
};
 
55
 
 
56
static wchar_t map_lcase[] = {
 
57
        [KC_Q] = 'q',
 
58
        [KC_W] = 'w',
 
59
        [KC_E] = 'e',
 
60
        [KC_R] = 'r',
 
61
        [KC_T] = 't',
 
62
        [KC_Y] = 'z',
 
63
        [KC_U] = 'u',
 
64
        [KC_I] = 'i',
 
65
        [KC_O] = 'o',
 
66
        [KC_P] = 'p',
 
67
 
 
68
        [KC_A] = 'a',
 
69
        [KC_S] = 's',
 
70
        [KC_D] = 'd',
 
71
        [KC_F] = 'f',
 
72
        [KC_G] = 'g',
 
73
        [KC_H] = 'h',
 
74
        [KC_J] = 'j',
 
75
        [KC_K] = 'k',
 
76
        [KC_L] = 'l',
 
77
 
 
78
        [KC_Z] = 'y',
 
79
        [KC_X] = 'x',
 
80
        [KC_C] = 'c',
 
81
        [KC_V] = 'v',
 
82
        [KC_B] = 'b',
 
83
        [KC_N] = 'n',
 
84
        [KC_M] = 'm',
 
85
};
 
86
 
 
87
static wchar_t map_ucase[] = {
 
88
        [KC_Q] = 'Q',
 
89
        [KC_W] = 'W',
 
90
        [KC_E] = 'E',
 
91
        [KC_R] = 'R',
 
92
        [KC_T] = 'T',
 
93
        [KC_Y] = 'Z',
 
94
        [KC_U] = 'U',
 
95
        [KC_I] = 'I',
 
96
        [KC_O] = 'O',
 
97
        [KC_P] = 'P',
 
98
 
 
99
        [KC_A] = 'A',
 
100
        [KC_S] = 'S',
 
101
        [KC_D] = 'D',
 
102
        [KC_F] = 'F',
 
103
        [KC_G] = 'G',
 
104
        [KC_H] = 'H',
 
105
        [KC_J] = 'J',
 
106
        [KC_K] = 'K',
 
107
        [KC_L] = 'L',
 
108
 
 
109
        [KC_Z] = 'Y',
 
110
        [KC_X] = 'X',
 
111
        [KC_C] = 'C',
 
112
        [KC_V] = 'V',
 
113
        [KC_B] = 'B',
 
114
        [KC_N] = 'N',
 
115
        [KC_M] = 'M',
 
116
};
 
117
 
 
118
static wchar_t map_not_shifted[] = {
 
119
        [KC_BACKTICK] = ';',
 
120
 
 
121
        [KC_1] = '+',
 
122
 
 
123
        [KC_MINUS] = '=',
 
124
 
 
125
        [KC_RBRACKET] = ')',
 
126
 
 
127
        [KC_QUOTE] = L'§',
 
128
 
 
129
        [KC_COMMA] = ',',
 
130
        [KC_PERIOD] = '.',
 
131
        [KC_SLASH] = '-',
 
132
};
 
133
 
 
134
static wchar_t map_shifted[] = {
 
135
        [KC_1] = '1',
 
136
        [KC_2] = '2',
 
137
        [KC_3] = '3',
 
138
        [KC_4] = '4',
 
139
        [KC_5] = '5',
 
140
        [KC_6] = '6',
 
141
        [KC_7] = '7',
 
142
        [KC_8] = '8',
 
143
        [KC_9] = '9',
 
144
        [KC_0] = '0',
 
145
 
 
146
        [KC_MINUS] = '%',
 
147
 
 
148
        [KC_LBRACKET] = '/',
 
149
        [KC_RBRACKET] = '(',
 
150
 
 
151
        [KC_SEMICOLON] = '"',
 
152
        [KC_QUOTE] = '!',
 
153
        [KC_BACKSLASH] = '\'',
 
154
 
 
155
        [KC_COMMA] = '?',
 
156
        [KC_PERIOD] = ':',
 
157
        [KC_SLASH] = '_',
 
158
};
 
159
 
 
160
static wchar_t map_ns_nocaps[] = {
 
161
        [KC_2] = L'ě',
 
162
        [KC_3] = L'š',
 
163
        [KC_4] = L'č',
 
164
        [KC_5] = L'ř',
 
165
        [KC_6] = L'ž',
 
166
        [KC_7] = L'ý',
 
167
        [KC_8] = L'á',
 
168
        [KC_9] = L'í',
 
169
        [KC_0] = L'é',
 
170
 
 
171
        [KC_LBRACKET] = L'ú',
 
172
        [KC_SEMICOLON] = L'ů'
 
173
};
 
174
 
 
175
static wchar_t map_ns_caps[] = {
 
176
        [KC_2] = L'Ě',
 
177
        [KC_3] = L'Š',
 
178
        [KC_4] = L'Č',
 
179
        [KC_5] = L'Ř',
 
180
        [KC_6] = L'Ž',
 
181
        [KC_7] = L'Ý',
 
182
        [KC_8] = L'Á',
 
183
        [KC_9] = L'Í',
 
184
        [KC_0] = L'É',
 
185
 
 
186
        [KC_LBRACKET] = L'Ú',
 
187
        [KC_SEMICOLON] = L'Ů'
 
188
};
 
189
 
 
190
static wchar_t map_neutral[] = {
 
191
        [KC_BACKSPACE] = '\b',
 
192
        [KC_TAB] = '\t',
 
193
        [KC_ENTER] = '\n',
 
194
        [KC_SPACE] = ' ',
 
195
 
 
196
        [KC_NSLASH] = '/',
 
197
        [KC_NTIMES] = '*',
 
198
        [KC_NMINUS] = '-',
 
199
        [KC_NPLUS] = '+',
 
200
        [KC_NENTER] = '\n'
 
201
};
 
202
 
 
203
static wchar_t map_numeric[] = {
 
204
        [KC_N7] = '7',
 
205
        [KC_N8] = '8',
 
206
        [KC_N9] = '9',
 
207
        [KC_N4] = '4',
 
208
        [KC_N5] = '5',
 
209
        [KC_N6] = '6',
 
210
        [KC_N1] = '1',
 
211
        [KC_N2] = '2',
 
212
        [KC_N3] = '3',
 
213
 
 
214
        [KC_N0] = '0',
 
215
        [KC_NPERIOD] = '.'
 
216
};
 
217
 
 
218
static wchar_t map_hacek_lcase[] = {
 
219
        [KC_E] = L'ě',
 
220
        [KC_R] = L'ř',
 
221
        [KC_T] = L'ť',
 
222
        [KC_Y] = L'ž',
 
223
        [KC_U] = L'ů',
 
224
 
 
225
        [KC_S] = L'š',
 
226
        [KC_D] = L'ď',
 
227
 
 
228
        [KC_C] = L'č',
 
229
        [KC_N] = L'ň'
 
230
};
 
231
 
 
232
static wchar_t map_hacek_ucase[] = {
 
233
        [KC_E] = L'Ě',
 
234
        [KC_R] = L'Ř',
 
235
        [KC_T] = L'Ť',
 
236
        [KC_Y] = L'Ž',
 
237
        [KC_U] = L'Ů',
 
238
 
 
239
        [KC_S] = L'Š',
 
240
        [KC_D] = L'Ď',
 
241
 
 
242
        [KC_C] = L'Č',
 
243
        [KC_N] = L'Ň'
 
244
};
 
245
 
 
246
static wchar_t map_carka_lcase[] = {
 
247
        [KC_E] = L'é',
 
248
        [KC_U] = L'ú',
 
249
        [KC_I] = L'í',
 
250
        [KC_O] = L'ó',
 
251
 
 
252
        [KC_A] = L'á',
 
253
 
 
254
        [KC_Z] = L'ý',
 
255
};
 
256
 
 
257
static wchar_t map_carka_ucase[] = {
 
258
        [KC_E] = L'É',
 
259
        [KC_U] = L'Ú',
 
260
        [KC_I] = L'Í',
 
261
        [KC_O] = L'Ó',
 
262
 
 
263
        [KC_A] = L'Á',
 
264
 
 
265
        [KC_Z] = L'Ý',
 
266
};
 
267
 
 
268
static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
 
269
{
 
270
        if (key >= map_length)
 
271
                return 0;
 
272
        return map[key];
 
273
}
 
274
 
 
275
static wchar_t parse_ms_hacek(console_event_t *ev)
 
276
{
 
277
        wchar_t c;
 
278
 
 
279
        mstate = ms_start;
 
280
 
 
281
        /* Produce no characters when Ctrl or Alt is pressed. */
 
282
        if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
 
283
                return 0;
 
284
 
 
285
        if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
 
286
                c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
 
287
        else
 
288
                c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
 
289
 
 
290
        return c;
 
291
}
 
292
 
 
293
static wchar_t parse_ms_carka(console_event_t *ev)
 
294
{
 
295
        wchar_t c;
 
296
 
 
297
        mstate = ms_start;
 
298
 
 
299
        /* Produce no characters when Ctrl or Alt is pressed. */
 
300
        if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
 
301
                return 0;
 
302
 
 
303
        if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
 
304
                c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
 
305
        else
 
306
                c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
 
307
 
 
308
        return c;
 
309
}
 
310
 
 
311
static wchar_t parse_ms_start(console_event_t *ev)
 
312
{
 
313
        wchar_t c;
 
314
 
 
315
        /* Produce no characters when Ctrl or Alt is pressed. */
 
316
        if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
 
317
                return 0;
 
318
 
 
319
        if (ev->key == KC_EQUALS) {
 
320
                if ((ev->mods & KM_SHIFT) != 0)
 
321
                        mstate = ms_hacek;
 
322
                else
 
323
                        mstate = ms_carka;
 
324
 
 
325
                return 0;
 
326
        }
 
327
 
 
328
        c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
 
329
        if (c != 0)
 
330
                return c;
 
331
 
 
332
        if ((ev->mods & KM_SHIFT) == 0) {
 
333
                if ((ev->mods & KM_CAPS_LOCK) != 0)
 
334
                        c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
 
335
                else
 
336
                        c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
 
337
 
 
338
                if (c != 0)
 
339
                        return c;
 
340
        }       
 
341
 
 
342
        if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
 
343
                c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
 
344
        else
 
345
                c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
 
346
 
 
347
        if (c != 0)
 
348
                return c;
 
349
 
 
350
        if ((ev->mods & KM_SHIFT) != 0)
 
351
                c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
 
352
        else
 
353
                c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
 
354
 
 
355
        if (c != 0)
 
356
                return c;
 
357
 
 
358
        if ((ev->mods & KM_NUM_LOCK) != 0)
 
359
                c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
 
360
        else
 
361
                c = 0;
 
362
 
 
363
        return c;
 
364
}
 
365
 
 
366
static bool key_is_mod(unsigned key)
 
367
{
 
368
        switch (key) {
 
369
        case KC_LSHIFT:
 
370
        case KC_RSHIFT:
 
371
        case KC_LALT:
 
372
        case KC_RALT:
 
373
        case KC_LCTRL:
 
374
        case KC_RCTRL:
 
375
                return true;
 
376
        default:
 
377
                return false;
 
378
        }
 
379
}
 
380
 
 
381
static void layout_reset(void)
 
382
{
 
383
        mstate = ms_start;
 
384
}
 
385
 
 
386
static wchar_t layout_parse_ev(console_event_t *ev)
 
387
{
 
388
        if (ev->type != KEY_PRESS)
 
389
                return 0;
 
390
        
 
391
        if (key_is_mod(ev->key))
 
392
                return 0;
 
393
        
 
394
        switch (mstate) {
 
395
        case ms_start:
 
396
                return parse_ms_start(ev);
 
397
        case ms_hacek:
 
398
                return parse_ms_hacek(ev);
 
399
        case ms_carka:
 
400
                return parse_ms_carka(ev);
 
401
        }
 
402
        
 
403
        return 0;
 
404
}
 
405
 
 
406
/**
 
407
 * @}
 
408
 */