001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.tools;
003
004import java.awt.event.KeyEvent;
005import java.awt.im.InputContext;
006import java.util.ArrayList;
007import java.util.LinkedHashMap;
008import java.util.List;
009import java.util.Locale;
010import java.util.Map;
011
012/**
013 * Keyboard utils.
014 * @since 14012
015 */
016public final class KeyboardUtils {
017
018    /**
019     * The flag for extended key codes.
020     */
021    public static final int EXTENDED_KEYCODE_FLAG = 0x01000000;
022
023    private static final Map<Integer, Integer> regularKeyCodesMap = new LinkedHashMap<>();
024    static {
025        // https://hg.openjdk.java.net/jdk/jdk/file/fa2f93f99dbc/src/java.desktop/share/classes/sun/awt/ExtendedKeyCodes.java#l67
026        regularKeyCodesMap.put(0x08, KeyEvent.VK_BACK_SPACE);
027        regularKeyCodesMap.put(0x09, KeyEvent.VK_TAB);
028        regularKeyCodesMap.put(0x0a, KeyEvent.VK_ENTER);
029        regularKeyCodesMap.put(0x1B, KeyEvent.VK_ESCAPE);
030        regularKeyCodesMap.put(0x20AC, KeyEvent.VK_EURO_SIGN);
031        regularKeyCodesMap.put(0x20, KeyEvent.VK_SPACE);
032        regularKeyCodesMap.put(0x21, KeyEvent.VK_EXCLAMATION_MARK);
033        regularKeyCodesMap.put(0x22, KeyEvent.VK_QUOTEDBL);
034        regularKeyCodesMap.put(0x23, KeyEvent.VK_NUMBER_SIGN);
035        regularKeyCodesMap.put(0x24, KeyEvent.VK_DOLLAR);
036        regularKeyCodesMap.put(0x26, KeyEvent.VK_AMPERSAND);
037        regularKeyCodesMap.put(0x27, KeyEvent.VK_QUOTE);
038        regularKeyCodesMap.put(0x28, KeyEvent.VK_LEFT_PARENTHESIS);
039        regularKeyCodesMap.put(0x29, KeyEvent.VK_RIGHT_PARENTHESIS);
040        regularKeyCodesMap.put(0x2A, KeyEvent.VK_ASTERISK);
041        regularKeyCodesMap.put(0x2B, KeyEvent.VK_PLUS);
042        regularKeyCodesMap.put(0x2C, KeyEvent.VK_COMMA);
043        regularKeyCodesMap.put(0x2D, KeyEvent.VK_MINUS);
044        regularKeyCodesMap.put(0x2E, KeyEvent.VK_PERIOD);
045        regularKeyCodesMap.put(0x2F, KeyEvent.VK_SLASH);
046        regularKeyCodesMap.put(0x30, KeyEvent.VK_0);
047        regularKeyCodesMap.put(0x31, KeyEvent.VK_1);
048        regularKeyCodesMap.put(0x32, KeyEvent.VK_2);
049        regularKeyCodesMap.put(0x33, KeyEvent.VK_3);
050        regularKeyCodesMap.put(0x34, KeyEvent.VK_4);
051        regularKeyCodesMap.put(0x35, KeyEvent.VK_5);
052        regularKeyCodesMap.put(0x36, KeyEvent.VK_6);
053        regularKeyCodesMap.put(0x37, KeyEvent.VK_7);
054        regularKeyCodesMap.put(0x38, KeyEvent.VK_8);
055        regularKeyCodesMap.put(0x39, KeyEvent.VK_9);
056        regularKeyCodesMap.put(0x3A, KeyEvent.VK_COLON);
057        regularKeyCodesMap.put(0x3B, KeyEvent.VK_SEMICOLON);
058        regularKeyCodesMap.put(0x3C, KeyEvent.VK_LESS);
059        regularKeyCodesMap.put(0x3D, KeyEvent.VK_EQUALS);
060        regularKeyCodesMap.put(0x3E, KeyEvent.VK_GREATER);
061        regularKeyCodesMap.put(0x40, KeyEvent.VK_AT);
062        regularKeyCodesMap.put(0x41, KeyEvent.VK_A);
063        regularKeyCodesMap.put(0x42, KeyEvent.VK_B);
064        regularKeyCodesMap.put(0x43, KeyEvent.VK_C);
065        regularKeyCodesMap.put(0x44, KeyEvent.VK_D);
066        regularKeyCodesMap.put(0x45, KeyEvent.VK_E);
067        regularKeyCodesMap.put(0x46, KeyEvent.VK_F);
068        regularKeyCodesMap.put(0x47, KeyEvent.VK_G);
069        regularKeyCodesMap.put(0x48, KeyEvent.VK_H);
070        regularKeyCodesMap.put(0x49, KeyEvent.VK_I);
071        regularKeyCodesMap.put(0x4A, KeyEvent.VK_J);
072        regularKeyCodesMap.put(0x4B, KeyEvent.VK_K);
073        regularKeyCodesMap.put(0x4C, KeyEvent.VK_L);
074        regularKeyCodesMap.put(0x4D, KeyEvent.VK_M);
075        regularKeyCodesMap.put(0x4E, KeyEvent.VK_N);
076        regularKeyCodesMap.put(0x4F, KeyEvent.VK_O);
077        regularKeyCodesMap.put(0x50, KeyEvent.VK_P);
078        regularKeyCodesMap.put(0x51, KeyEvent.VK_Q);
079        regularKeyCodesMap.put(0x52, KeyEvent.VK_R);
080        regularKeyCodesMap.put(0x53, KeyEvent.VK_S);
081        regularKeyCodesMap.put(0x54, KeyEvent.VK_T);
082        regularKeyCodesMap.put(0x55, KeyEvent.VK_U);
083        regularKeyCodesMap.put(0x56, KeyEvent.VK_V);
084        regularKeyCodesMap.put(0x57, KeyEvent.VK_W);
085        regularKeyCodesMap.put(0x58, KeyEvent.VK_X);
086        regularKeyCodesMap.put(0x59, KeyEvent.VK_Y);
087        regularKeyCodesMap.put(0x5A, KeyEvent.VK_Z);
088        regularKeyCodesMap.put(0x5B, KeyEvent.VK_OPEN_BRACKET);
089        regularKeyCodesMap.put(0x5C, KeyEvent.VK_BACK_SLASH);
090        regularKeyCodesMap.put(0x5D, KeyEvent.VK_CLOSE_BRACKET);
091        regularKeyCodesMap.put(0x5E, KeyEvent.VK_CIRCUMFLEX);
092        regularKeyCodesMap.put(0x5F, KeyEvent.VK_UNDERSCORE);
093        regularKeyCodesMap.put(0x60, KeyEvent.VK_BACK_QUOTE);
094        regularKeyCodesMap.put(0x61, KeyEvent.VK_A);
095        regularKeyCodesMap.put(0x62, KeyEvent.VK_B);
096        regularKeyCodesMap.put(0x63, KeyEvent.VK_C);
097        regularKeyCodesMap.put(0x64, KeyEvent.VK_D);
098        regularKeyCodesMap.put(0x65, KeyEvent.VK_E);
099        regularKeyCodesMap.put(0x66, KeyEvent.VK_F);
100        regularKeyCodesMap.put(0x67, KeyEvent.VK_G);
101        regularKeyCodesMap.put(0x68, KeyEvent.VK_H);
102        regularKeyCodesMap.put(0x69, KeyEvent.VK_I);
103        regularKeyCodesMap.put(0x6A, KeyEvent.VK_J);
104        regularKeyCodesMap.put(0x6B, KeyEvent.VK_K);
105        regularKeyCodesMap.put(0x6C, KeyEvent.VK_L);
106        regularKeyCodesMap.put(0x6D, KeyEvent.VK_M);
107        regularKeyCodesMap.put(0x6E, KeyEvent.VK_N);
108        regularKeyCodesMap.put(0x6F, KeyEvent.VK_O);
109        regularKeyCodesMap.put(0x70, KeyEvent.VK_P);
110        regularKeyCodesMap.put(0x71, KeyEvent.VK_Q);
111        regularKeyCodesMap.put(0x72, KeyEvent.VK_R);
112        regularKeyCodesMap.put(0x73, KeyEvent.VK_S);
113        regularKeyCodesMap.put(0x74, KeyEvent.VK_T);
114        regularKeyCodesMap.put(0x75, KeyEvent.VK_U);
115        regularKeyCodesMap.put(0x76, KeyEvent.VK_V);
116        regularKeyCodesMap.put(0x77, KeyEvent.VK_W);
117        regularKeyCodesMap.put(0x78, KeyEvent.VK_X);
118        regularKeyCodesMap.put(0x79, KeyEvent.VK_Y);
119        regularKeyCodesMap.put(0x7A, KeyEvent.VK_Z);
120        regularKeyCodesMap.put(0x7B, KeyEvent.VK_BRACELEFT);
121        regularKeyCodesMap.put(0x7D, KeyEvent.VK_BRACERIGHT);
122        regularKeyCodesMap.put(0x7F, KeyEvent.VK_DELETE);
123        regularKeyCodesMap.put(0xA1, KeyEvent.VK_INVERTED_EXCLAMATION_MARK);
124    }
125
126    private KeyboardUtils() {
127        // Hide default constructor for utils classes
128    }
129
130    /**
131     * Returns Keycodes declared in {@link KeyEvent} with corresponding Unicode values.
132     * @return Map of KeyEvent VK_ characters constants indexed by their unicode value
133     */
134    public static Map<Integer, Integer> getRegularKeyCodesMap() {
135        return regularKeyCodesMap;
136    }
137
138    /**
139     * Returns the plausible characters expected to be displayed for the given physical key and current input locale.
140     * Physical keys are defined as per <a href="https://en.wikipedia.org/wiki/ISO/IEC_9995#ISO/IEC_9995-2">ISO/IEC 9995-2</a>
141     * keyboard layout. Only E00 is currently supported.
142     * @param row row letter as per ISO/IEC 9995-2 (A to E)
143     * @param column column number as per ISO/IEC 9995-2 (0 to 14, plus 99)
144     * @return the plausible characters expected to be displayed for the given physical key and current input locale
145     */
146    public static List<Character> getCharactersForKey(char row, int column) {
147        return getCharactersForKey(row, column, InputContext.getInstance().getLocale());
148    }
149
150    /**
151     * Returns the plausible characters expected to be displayed for the given physical key and locale.
152     * Physical keys are defined as per <a href="https://en.wikipedia.org/wiki/ISO/IEC_9995#ISO/IEC_9995-2">ISO/IEC 9995-2</a>
153     * keyboard layout. Only E00 is currently supported.
154     * @param row row letter as per ISO/IEC 9995-2 (A to E)
155     * @param column column number as per ISO/IEC 9995-2 (0 to 14, plus 99)
156     * @param l locale (defining language and country)
157     * @return the plausible characters expected to be displayed for the given physical key and locale
158     */
159    public static List<Character> getCharactersForKey(char row, int column, Locale l) {
160        if (l == null) {
161            l = I18n.getOriginalLocale();
162        }
163        if ('E' == row && 0 == column) {
164            List<Character> result = new ArrayList<>();
165
166            // One good resource:
167            // https://docs.microsoft.com/en-us/globalization/windows-keyboard-layouts
168
169            // By language. Codes noted below are extended ones obtained with Windows OSK
170            switch (l.getLanguage()) {
171            case "ar": // Arabic
172                result.add('ذ'); // https://docs.microsoft.com/fr-fr/globalization/keyboards/kbda1.html
173                result.add('>'); // https://docs.microsoft.com/fr-fr/globalization/keyboards/kbda2.html
174                break;
175            case "fr": // French
176                if ("CA".equals(l.getCountry())) {
177                    // Canada, see https://en.wikipedia.org/wiki/QWERTY#Canadian_French
178                    result.add('#');
179                } else if (!"LU".equals(l.getCountry())) {
180                    // France and Belgium, https://en.wikipedia.org/wiki/AZERTY
181                    result.add('²');
182                }
183                // BÉPO, https://en.wikipedia.org/wiki/Keyboard_layout#B%C3%89PO
184                result.add('$');
185                if (PlatformManager.isPlatformUnixoid()) {
186                    // X11 fr-latin9
187                    result.add('œ');
188                }
189                break;
190            case "sq": // Albanian
191            case "it": // Italian
192            case "pt": // Portuguese
193                if ("BR".equals(l.getCountry())) {
194                    // Brazil, https://en.wikipedia.org/wiki/QWERTY#Brazil
195                    result.add('\'');
196                } else {
197                    // Albanian, https://en.wikipedia.org/wiki/Albanian_keyboard_layout
198                    //           https://docs.microsoft.com/fr-fr/globalization/keyboards/kbdal.html
199                    // Italian, https://en.wikipedia.org/wiki/QWERTY#Italian
200                    // Portugal, https://en.wikipedia.org/wiki/QWERTY#Portugal
201                    result.add('\\');
202                }
203                break;
204            case "de": // German
205                // https://en.wikipedia.org/wiki/German_keyboard_layout
206                result.add((char) KeyEvent.VK_DEAD_CIRCUMFLEX);
207                result.add('ˆ'); // U+02C6 : dead/modifier circumflex
208                break;
209            case "cs": // Czech
210            case "he": // Hebrew starting from Java 17 - https://bugs.openjdk.java.net/browse/JDK-8263202
211            case "iw": // Hebrew before Java 17
212                // https://en.wikipedia.org/wiki/QWERTZ#Czech_(QWERTZ)
213                // https://en.wikipedia.org/wiki/Hebrew_keyboard
214                result.add(';');
215                break;
216            case "hu":
217                // Hungarian, https://en.wikipedia.org/wiki/QWERTZ#Hungary
218                result.add('0');
219                break;
220            case "bs": // Bosnian
221            case "hr": // Croatian
222            case "sl": // Slovenian
223            case "sr": // Serbian
224                // https://en.wikipedia.org/wiki/QWERTZ#South_Slavic_Latin
225                result.add('¸'); // Copied from https://upload.wikimedia.org/wikipedia/commons/2/2e/KB_Slovene.svg
226                break;
227            case "ro": // Romanian
228                // https://en.wikipedia.org/wiki/QWERTZ#Romanian
229                result.add(']');
230                break;
231            case "da": // Danish
232            case "fo": // Faroese
233                // https://en.wikipedia.org/wiki/QWERTY#Danish
234                // https://en.wikipedia.org/wiki/QWERTY#Faroese
235                result.add('½'); // Copied from https://upload.wikimedia.org/wikipedia/commons/4/46/KB_Danish_text.svg
236                break;
237            case "nl": // Dutch
238                // https://en.wikipedia.org/wiki/QWERTY#Dutch_(Netherlands)
239                result.add('@');
240                break;
241            case "et": // Estonian
242                // https://en.wikipedia.org/wiki/QWERTY#Estonian
243                result.add((char) KeyEvent.VK_DEAD_CARON); // https://en.wikipedia.org/wiki/Caron
244                result.add('ˇ'); // U+02C7 : dead key/modifier
245                break;
246            case "is": // Icelandic
247                // https://en.wikipedia.org/wiki/Icelandic_keyboard_layout
248                result.add('°'); // https://en.wikipedia.org/wiki/Ring_(diacritic)
249                // FIXME It doesn't work with Java 8: [KEY_PRESSED,keyCode=0,keyChar=Undefined keyChar,extendedKeyCode=0x0]
250                break;
251            case "es": // Spanish
252                // Latin America only, https://en.wikipedia.org/wiki/QWERTY#Latin_America
253                if (!"ES".equals(l.getCountry())) {
254                    result.add('|');
255                }
256                break;
257            case "tr": // Turkish
258                // https://en.wikipedia.org/wiki/QWERTY#Turkish_(Q-keyboard)
259                // https://en.wikipedia.org/wiki/Keyboard_layout#Turkish_(F-keyboard)
260                result.add('"');
261                result.add('*');
262                break;
263            default:
264                // Do nothing
265            }
266
267            // By country regardless of language
268            switch (l.getCountry()) {
269            case "LU": // Luxembourg
270                result.add('²');
271                // fall-through
272            case "CH": // Swiss
273            case "LI": // Liechenstein
274            case "FI": // Finland
275            case "SE": // Sweden
276                // https://en.wikipedia.org/wiki/QWERTZ#Switzerland_(German,_French,_Italian,_Romansh),_Liechtenstein,_Luxembourg
277                // https://en.wikipedia.org/wiki/QWERTY#Finnish_multilingual
278                // https://en.wikipedia.org/wiki/QWERTY#Swedish
279                result.add('§');
280                break;
281            case "CA": // Canada
282                // https://en.wikipedia.org/wiki/CSA_keyboard
283                result.add('/'); // 2F
284                break;
285            case "NO": // Norway
286                // https://en.wikipedia.org/wiki/QWERTY#Norwegian
287                result.add('|');
288                break;
289            case "ES": // Spain
290                // https://en.wikipedia.org/wiki/QWERTY#Spain,_also_known_as_Spanish_(International_sort)
291                result.add('º'); // https://en.wikipedia.org/wiki/Ordinal_indicator
292                // FIXME It doesn't work with Java 8: [KEY_PRESSED,keyCode=0,keyChar=Undefined keyChar,extendedKeyCode=0x0]
293                break;
294            default:
295                // Do nothing
296            }
297
298            // UK Apple, https://en.wikipedia.org/wiki/QWERTY#UK_Apple_keyboard
299            // International English Apple, https://en.wikipedia.org/wiki/QWERTY#Apple_International_English_Keyboard
300            if (PlatformManager.isPlatformOsx()) {
301                result.add('§'); // https://en.wikipedia.org/wiki/Section_sign
302            }
303
304            // Add default US QWERTY keys, https://en.wikipedia.org/wiki/QWERTY
305            // Works also for Dvorak, https://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard
306            result.add('`'); // U+0060: On US QWERTY, this is not a dead key
307            result.add((char) KeyEvent.VK_DEAD_GRAVE);
308            result.add('ˋ'); // U+02CB: On International QWERTY, this is a dead key
309            return result;
310        }
311        throw new UnsupportedOperationException();
312    }
313
314    /**
315     * Returns the extended key codes that we are susceptible to receive given the locale.
316     * @param locale locale
317     * @return the extended key codes that we are susceptible to receive given the locale
318     */
319    public static Map<Integer, Character> getExtendedKeyCodes(Locale locale) {
320        // Last update: 2017-09-12
321        // https://hg.openjdk.java.net/jdk/jdk/file/fa2f93f99dbc/src/java.desktop/share/classes/sun/awt/ExtendedKeyCodes.java#l166
322        // Characters found at least on one keyboard layout
323        Map<Integer, Character> map = new LinkedHashMap<>();
324        // Add latin characters and symbols for everyone
325        addLatinCharacters(map);
326        addSymbolCharacters(map);
327
328        if (locale == null) {
329            locale = I18n.getOriginalLocale();
330        }
331
332        // Detect current script
333        // https://en.wikipedia.org/wiki/ISO_15924#List_of_codes
334        switch (locale.getScript()) {
335            case "Arab": // https://en.wikipedia.org/wiki/Arabic_script
336            case "Aran": // https://en.wikipedia.org/wiki/Nasta%CA%BFl%C4%ABq_script
337                addArabicCharacters(map);
338                break;
339            case "Armn": // https://en.wikipedia.org/wiki/Armenian_alphabet
340                addArmenianCharacters(map);
341                break;
342            case "Cyrl": // https://en.wikipedia.org/wiki/Cyrillic_script
343                addCyrillicCharacters(map);
344                break;
345            case "Geok": // https://en.wikipedia.org/wiki/Georgian_scripts#Nuskhuri
346            case "Geor": // https://en.wikipedia.org/wiki/Georgian_scripts#Mkhedruli
347                addGeorgianCharacters(map);
348                break;
349            case "Grek": // https://en.wikipedia.org/wiki/Greek_alphabet
350                addGreekCharacters(map);
351                break;
352            case "Hebr": // https://en.wikipedia.org/wiki/Hebrew_alphabet
353                addHebrewCharacters(map);
354                break;
355            case "Hira": // https://en.wikipedia.org/wiki/Hiragana
356            case "Jpan": // https://en.wikipedia.org/wiki/Japanese_writing_system
357            case "Kana": // https://en.wikipedia.org/wiki/Katakana
358                addJapaneseCharacters(map);
359                break;
360            case "Thai": // https://en.wikipedia.org/wiki/Thai_alphabet
361                addThaiCharacters(map);
362                break;
363            default:
364                // Do nothing
365        }
366
367        return map;
368    }
369
370    static void addLatinCharacters(Map<Integer, Character> map) {
371        map.put(EXTENDED_KEYCODE_FLAG + 0x0060, '`'); // GRAVE ACCENT
372        map.put(EXTENDED_KEYCODE_FLAG + 0x007C, '|'); // VERTICAL LINE
373        map.put(EXTENDED_KEYCODE_FLAG + 0x007E, '~'); // TILDE
374        map.put(EXTENDED_KEYCODE_FLAG + 0x00A2, '¢'); // CENT SIGN
375        map.put(EXTENDED_KEYCODE_FLAG + 0x00A3, '£'); // POUND SIGN
376        map.put(EXTENDED_KEYCODE_FLAG + 0x00A5, '¥'); // YEN SIGN
377        map.put(EXTENDED_KEYCODE_FLAG + 0x00A7, '§'); // SECTION SIGN
378        map.put(EXTENDED_KEYCODE_FLAG + 0x00A8, '¨'); // DIAERESIS
379        map.put(EXTENDED_KEYCODE_FLAG + 0x00AB, '«'); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
380        map.put(EXTENDED_KEYCODE_FLAG + 0x00B0, '°'); // DEGREE SIGN
381        map.put(EXTENDED_KEYCODE_FLAG + 0x00B1, '±'); // PLUS-MINUS SIGN
382        map.put(EXTENDED_KEYCODE_FLAG + 0x00B2, '²'); // SUPERSCRIPT TWO
383        map.put(EXTENDED_KEYCODE_FLAG + 0x00B3, '³'); // SUPERSCRIPT THREE
384        map.put(EXTENDED_KEYCODE_FLAG + 0x00B4, '´'); // ACUTE ACCENT
385        map.put(EXTENDED_KEYCODE_FLAG + 0x00B5, 'µ'); // MICRO SIGN
386        map.put(EXTENDED_KEYCODE_FLAG + 0x00B6, '¶'); // PILCROW SIGN
387        map.put(EXTENDED_KEYCODE_FLAG + 0x00B7, '·'); // MIDDLE DOT
388        map.put(EXTENDED_KEYCODE_FLAG + 0x00B9, '¹'); // SUPERSCRIPT ONE
389        map.put(EXTENDED_KEYCODE_FLAG + 0x00BA, 'º'); // MASCULINE ORDINAL INDICATOR
390        map.put(EXTENDED_KEYCODE_FLAG + 0x00BB, '»'); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
391        map.put(EXTENDED_KEYCODE_FLAG + 0x00BC, '¼'); // VULGAR FRACTION ONE QUARTER
392        map.put(EXTENDED_KEYCODE_FLAG + 0x00BD, '½'); // VULGAR FRACTION ONE HALF
393        map.put(EXTENDED_KEYCODE_FLAG + 0x00BE, '¾'); // VULGAR FRACTION THREE QUARTERS
394        map.put(EXTENDED_KEYCODE_FLAG + 0x00BF, '¿'); // INVERTED QUESTION MARK
395        map.put(EXTENDED_KEYCODE_FLAG + 0x00C4, 'Ä'); // LATIN CAPITAL LETTER A WITH DIAERESIS
396        map.put(EXTENDED_KEYCODE_FLAG + 0x00C5, 'Å'); // LATIN CAPITAL LETTER A WITH RING ABOVE
397        map.put(EXTENDED_KEYCODE_FLAG + 0x00C6, 'Æ'); // LATIN CAPITAL LETTER AE
398        map.put(EXTENDED_KEYCODE_FLAG + 0x00C7, 'Ç'); // LATIN CAPITAL LETTER C WITH CEDILLA
399        map.put(EXTENDED_KEYCODE_FLAG + 0x00D1, 'Ñ'); // LATIN CAPITAL LETTER N WITH TILDE
400        map.put(EXTENDED_KEYCODE_FLAG + 0x00D6, 'Ö'); // LATIN CAPITAL LETTER O WITH DIAERESIS
401        map.put(EXTENDED_KEYCODE_FLAG + 0x00D7, '×'); // MULTIPLICATION SIGN
402        map.put(EXTENDED_KEYCODE_FLAG + 0x00D8, 'Ø'); // LATIN CAPITAL LETTER O WITH STROKE
403        map.put(EXTENDED_KEYCODE_FLAG + 0x00DF, 'ß'); // LATIN SMALL LETTER SHARP S
404        map.put(EXTENDED_KEYCODE_FLAG + 0x00E0, 'à'); // LATIN SMALL LETTER A WITH GRAVE
405        map.put(EXTENDED_KEYCODE_FLAG + 0x00E1, 'á'); // LATIN SMALL LETTER A WITH ACUTE
406        map.put(EXTENDED_KEYCODE_FLAG + 0x00E2, 'â'); // LATIN SMALL LETTER A WITH CIRCUMFLEX
407        map.put(EXTENDED_KEYCODE_FLAG + 0x00E4, 'ä'); // LATIN SMALL LETTER A WITH DIAERESIS
408        map.put(EXTENDED_KEYCODE_FLAG + 0x00E5, 'å'); // LATIN SMALL LETTER A WITH RING ABOVE
409        map.put(EXTENDED_KEYCODE_FLAG + 0x00E6, 'æ'); // LATIN SMALL LETTER AE
410        map.put(EXTENDED_KEYCODE_FLAG + 0x00E7, 'ç'); // LATIN SMALL LETTER C WITH CEDILLA
411        map.put(EXTENDED_KEYCODE_FLAG + 0x00E8, 'è'); // LATIN SMALL LETTER E WITH GRAVE
412        map.put(EXTENDED_KEYCODE_FLAG + 0x00E9, 'é'); // LATIN SMALL LETTER E WITH ACUTE
413        map.put(EXTENDED_KEYCODE_FLAG + 0x00EA, 'ê'); // LATIN SMALL LETTER E WITH CIRCUMFLEX
414        map.put(EXTENDED_KEYCODE_FLAG + 0x00EB, 'ë'); // LATIN SMALL LETTER E WITH DIAERESIS
415        map.put(EXTENDED_KEYCODE_FLAG + 0x00EC, 'ì'); // LATIN SMALL LETTER I WITH GRAVE
416        map.put(EXTENDED_KEYCODE_FLAG + 0x00ED, 'í'); // LATIN SMALL LETTER I WITH ACUTE
417        map.put(EXTENDED_KEYCODE_FLAG + 0x00EE, 'î'); // LATIN SMALL LETTER I WITH CIRCUMFLEX
418        map.put(EXTENDED_KEYCODE_FLAG + 0x00F0, 'ð'); // LATIN SMALL LETTER ETH
419        map.put(EXTENDED_KEYCODE_FLAG + 0x00F1, 'ñ'); // LATIN SMALL LETTER N WITH TILDE
420        map.put(EXTENDED_KEYCODE_FLAG + 0x00F2, 'ò'); // LATIN SMALL LETTER O WITH GRAVE
421        map.put(EXTENDED_KEYCODE_FLAG + 0x00F3, 'ó'); // LATIN SMALL LETTER O WITH ACUTE
422        map.put(EXTENDED_KEYCODE_FLAG + 0x00F4, 'ô'); // LATIN SMALL LETTER O WITH CIRCUMFLEX
423        map.put(EXTENDED_KEYCODE_FLAG + 0x00F5, 'õ'); // LATIN SMALL LETTER O WITH TILDE
424        map.put(EXTENDED_KEYCODE_FLAG + 0x00F6, 'ö'); // LATIN SMALL LETTER O WITH DIAERESIS
425        map.put(EXTENDED_KEYCODE_FLAG + 0x00F7, '÷'); // DIVISION SIGN
426        map.put(EXTENDED_KEYCODE_FLAG + 0x00F8, 'ø'); // LATIN SMALL LETTER O WITH STROKE
427        map.put(EXTENDED_KEYCODE_FLAG + 0x00F9, 'ù'); // LATIN SMALL LETTER U WITH GRAVE
428        map.put(EXTENDED_KEYCODE_FLAG + 0x00FA, 'ú'); // LATIN SMALL LETTER U WITH ACUTE
429        map.put(EXTENDED_KEYCODE_FLAG + 0x00FB, 'û'); // LATIN SMALL LETTER U WITH CIRCUMFLEX
430        map.put(EXTENDED_KEYCODE_FLAG + 0x00FC, 'ü'); // LATIN SMALL LETTER U WITH DIAERESIS
431        map.put(EXTENDED_KEYCODE_FLAG + 0x00FD, 'ý'); // LATIN SMALL LETTER Y WITH ACUTE
432        map.put(EXTENDED_KEYCODE_FLAG + 0x00FE, 'þ'); // LATIN SMALL LETTER THORN
433        map.put(EXTENDED_KEYCODE_FLAG + 0x0101, 'ā'); // LATIN SMALL LETTER A WITH MACRON
434        map.put(EXTENDED_KEYCODE_FLAG + 0x0103, 'ă'); // LATIN SMALL LETTER A WITH BREVE
435        map.put(EXTENDED_KEYCODE_FLAG + 0x0105, 'ą'); // LATIN SMALL LETTER A WITH OGONEK
436        map.put(EXTENDED_KEYCODE_FLAG + 0x0107, 'ć'); // LATIN SMALL LETTER C WITH ACUTE
437        map.put(EXTENDED_KEYCODE_FLAG + 0x0109, 'ĉ'); // LATIN SMALL LETTER C WITH CIRCUMFLEX
438        map.put(EXTENDED_KEYCODE_FLAG + 0x010B, 'ċ'); // LATIN SMALL LETTER C WITH DOT ABOVE
439        map.put(EXTENDED_KEYCODE_FLAG + 0x010D, 'č'); // LATIN SMALL LETTER C WITH CARON
440        map.put(EXTENDED_KEYCODE_FLAG + 0x0111, 'đ'); // LATIN SMALL LETTER D WITH STROKE
441        map.put(EXTENDED_KEYCODE_FLAG + 0x0113, 'ē'); // LATIN SMALL LETTER E WITH MACRON
442        map.put(EXTENDED_KEYCODE_FLAG + 0x0117, 'ė'); // LATIN SMALL LETTER E WITH DOT ABOVE
443        map.put(EXTENDED_KEYCODE_FLAG + 0x0119, 'ę'); // LATIN SMALL LETTER E WITH OGONEK
444        map.put(EXTENDED_KEYCODE_FLAG + 0x011B, 'ě'); // LATIN SMALL LETTER E WITH CARON
445        map.put(EXTENDED_KEYCODE_FLAG + 0x011D, 'ĝ'); // LATIN SMALL LETTER G WITH CIRCUMFLEX
446        map.put(EXTENDED_KEYCODE_FLAG + 0x011F, 'ğ'); // LATIN SMALL LETTER G WITH BREVE
447        map.put(EXTENDED_KEYCODE_FLAG + 0x0121, 'ġ'); // LATIN SMALL LETTER G WITH DOT ABOVE
448        map.put(EXTENDED_KEYCODE_FLAG + 0x0123, 'ģ'); // LATIN SMALL LETTER G WITH CEDILLA
449        map.put(EXTENDED_KEYCODE_FLAG + 0x0125, 'ĥ'); // LATIN SMALL LETTER H WITH CIRCUMFLEX
450        map.put(EXTENDED_KEYCODE_FLAG + 0x0127, 'ħ'); // LATIN SMALL LETTER H WITH STROKE
451        map.put(EXTENDED_KEYCODE_FLAG + 0x012B, 'ī'); // LATIN SMALL LETTER I WITH MACRON
452        map.put(EXTENDED_KEYCODE_FLAG + 0x012F, 'į'); // LATIN SMALL LETTER I WITH OGONEK
453        map.put(EXTENDED_KEYCODE_FLAG + 0x0130, 'İ'); // LATIN CAPITAL LETTER I WITH DOT ABOVE
454        map.put(EXTENDED_KEYCODE_FLAG + 0x0131, 'ı'); // LATIN SMALL LETTER DOTLESS I
455        map.put(EXTENDED_KEYCODE_FLAG + 0x0135, 'ĵ'); // LATIN SMALL LETTER J WITH CIRCUMFLEX
456        map.put(EXTENDED_KEYCODE_FLAG + 0x0137, 'ķ'); // LATIN SMALL LETTER K WITH CEDILLA
457        map.put(EXTENDED_KEYCODE_FLAG + 0x0138, 'ĸ'); // LATIN SMALL LETTER KRA
458        map.put(EXTENDED_KEYCODE_FLAG + 0x013C, 'ļ'); // LATIN SMALL LETTER L WITH CEDILLA
459        map.put(EXTENDED_KEYCODE_FLAG + 0x013E, 'ľ'); // LATIN SMALL LETTER L WITH CARON
460        map.put(EXTENDED_KEYCODE_FLAG + 0x0142, 'ł'); // LATIN SMALL LETTER L WITH STROKE
461        map.put(EXTENDED_KEYCODE_FLAG + 0x0146, 'ņ'); // LATIN SMALL LETTER N WITH CEDILLA
462        map.put(EXTENDED_KEYCODE_FLAG + 0x0148, 'ň'); // LATIN SMALL LETTER N WITH CARON
463        map.put(EXTENDED_KEYCODE_FLAG + 0x014B, 'ŋ'); // LATIN SMALL LETTER ENG
464        map.put(EXTENDED_KEYCODE_FLAG + 0x014D, 'ō'); // LATIN SMALL LETTER O WITH MACRON
465        map.put(EXTENDED_KEYCODE_FLAG + 0x0151, 'ő'); // LATIN SMALL LETTER O WITH DOUBLE ACUTE
466        map.put(EXTENDED_KEYCODE_FLAG + 0x0153, 'œ'); // LATIN SMALL LIGATURE OE
467        map.put(EXTENDED_KEYCODE_FLAG + 0x0157, 'ŗ'); // LATIN SMALL LETTER R WITH CEDILLA
468        map.put(EXTENDED_KEYCODE_FLAG + 0x0159, 'ř'); // LATIN SMALL LETTER R WITH CARON
469        map.put(EXTENDED_KEYCODE_FLAG + 0x015B, 'ś'); // LATIN SMALL LETTER S WITH ACUTE
470        map.put(EXTENDED_KEYCODE_FLAG + 0x015D, 'ŝ'); // LATIN SMALL LETTER S WITH CIRCUMFLEX
471        map.put(EXTENDED_KEYCODE_FLAG + 0x015F, 'ş'); // LATIN SMALL LETTER S WITH CEDILLA
472        map.put(EXTENDED_KEYCODE_FLAG + 0x0161, 'š'); // LATIN SMALL LETTER S WITH CARON
473        map.put(EXTENDED_KEYCODE_FLAG + 0x0163, 'ţ'); // LATIN SMALL LETTER T WITH CEDILLA
474        map.put(EXTENDED_KEYCODE_FLAG + 0x0165, 'ť'); // LATIN SMALL LETTER T WITH CARON
475        map.put(EXTENDED_KEYCODE_FLAG + 0x0167, 'ŧ'); // LATIN SMALL LETTER T WITH STROKE
476        map.put(EXTENDED_KEYCODE_FLAG + 0x016B, 'ū'); // LATIN SMALL LETTER U WITH MACRON
477        map.put(EXTENDED_KEYCODE_FLAG + 0x016D, 'ŭ'); // LATIN SMALL LETTER U WITH BREVE
478        map.put(EXTENDED_KEYCODE_FLAG + 0x016F, 'ů'); // LATIN SMALL LETTER U WITH RING ABOVE
479        map.put(EXTENDED_KEYCODE_FLAG + 0x0171, 'ű'); // LATIN SMALL LETTER U WITH DOUBLE ACUTE
480        map.put(EXTENDED_KEYCODE_FLAG + 0x0173, 'ų'); // LATIN SMALL LETTER U WITH OGONEK
481        map.put(EXTENDED_KEYCODE_FLAG + 0x017C, 'ż'); // LATIN SMALL LETTER Z WITH DOT ABOVE
482        map.put(EXTENDED_KEYCODE_FLAG + 0x017E, 'ž'); // LATIN SMALL LETTER Z WITH CARON
483        map.put(EXTENDED_KEYCODE_FLAG + 0x01A1, 'ơ'); // LATIN SMALL LETTER O WITH HORN
484        map.put(EXTENDED_KEYCODE_FLAG + 0x01B0, 'ư'); // LATIN SMALL LETTER U WITH HORN
485        map.put(EXTENDED_KEYCODE_FLAG + 0x01E7, 'ǧ'); // LATIN SMALL LETTER G WITH CARON
486        map.put(EXTENDED_KEYCODE_FLAG + 0x0259, 'ə'); // LATIN SMALL LETTER SCHWA
487        map.put(EXTENDED_KEYCODE_FLAG + 0x02D9, '˙'); // DOT ABOVE
488        map.put(EXTENDED_KEYCODE_FLAG + 0x02DB, '˛'); // OGONEK
489        map.put(EXTENDED_KEYCODE_FLAG + 0x1EB9, 'ẹ'); // LATIN SMALL LETTER E WITH DOT BELOW
490        map.put(EXTENDED_KEYCODE_FLAG + 0x1ECB, 'ị'); // LATIN SMALL LETTER I WITH DOT BELOW
491        map.put(EXTENDED_KEYCODE_FLAG + 0x1ECD, 'ọ'); // LATIN SMALL LETTER O WITH DOT BELOW
492        map.put(EXTENDED_KEYCODE_FLAG + 0x1EE5, 'ụ'); // LATIN SMALL LETTER U WITH DOT BELOW
493    }
494
495    static void addGreekCharacters(Map<Integer, Character> map) {
496        map.put(EXTENDED_KEYCODE_FLAG + 0x03B1, 'α'); // GREEK SMALL LETTER ALPHA
497        map.put(EXTENDED_KEYCODE_FLAG + 0x03B2, 'β'); // GREEK SMALL LETTER BETA
498        map.put(EXTENDED_KEYCODE_FLAG + 0x03B3, 'γ'); // GREEK SMALL LETTER GAMMA
499        map.put(EXTENDED_KEYCODE_FLAG + 0x03B4, 'δ'); // GREEK SMALL LETTER DELTA
500        map.put(EXTENDED_KEYCODE_FLAG + 0x03B5, 'ε'); // GREEK SMALL LETTER EPSILON
501        map.put(EXTENDED_KEYCODE_FLAG + 0x03B6, 'ζ'); // GREEK SMALL LETTER ZETA
502        map.put(EXTENDED_KEYCODE_FLAG + 0x03B7, 'η'); // GREEK SMALL LETTER ETA
503        map.put(EXTENDED_KEYCODE_FLAG + 0x03B8, 'θ'); // GREEK SMALL LETTER THETA
504        map.put(EXTENDED_KEYCODE_FLAG + 0x03B9, 'ι'); // GREEK SMALL LETTER IOTA
505        map.put(EXTENDED_KEYCODE_FLAG + 0x03BA, 'κ'); // GREEK SMALL LETTER KAPPA
506        map.put(EXTENDED_KEYCODE_FLAG + 0x03BB, 'λ'); // GREEK SMALL LETTER LAMDA
507        map.put(EXTENDED_KEYCODE_FLAG + 0x03BC, 'μ'); // GREEK SMALL LETTER MU
508        map.put(EXTENDED_KEYCODE_FLAG + 0x03BD, 'ν'); // GREEK SMALL LETTER NU
509        map.put(EXTENDED_KEYCODE_FLAG + 0x03BE, 'ξ'); // GREEK SMALL LETTER XI
510        map.put(EXTENDED_KEYCODE_FLAG + 0x03BF, 'ο'); // GREEK SMALL LETTER OMICRON
511        map.put(EXTENDED_KEYCODE_FLAG + 0x03C0, 'π'); // GREEK SMALL LETTER PI
512        map.put(EXTENDED_KEYCODE_FLAG + 0x03C1, 'ρ'); // GREEK SMALL LETTER RHO
513        map.put(EXTENDED_KEYCODE_FLAG + 0x03C2, 'ς'); // GREEK SMALL LETTER FINAL SIGMA
514        map.put(EXTENDED_KEYCODE_FLAG + 0x03C3, 'σ'); // GREEK SMALL LETTER SIGMA
515        map.put(EXTENDED_KEYCODE_FLAG + 0x03C4, 'τ'); // GREEK SMALL LETTER TAU
516        map.put(EXTENDED_KEYCODE_FLAG + 0x03C5, 'υ'); // GREEK SMALL LETTER UPSILON
517        map.put(EXTENDED_KEYCODE_FLAG + 0x03C6, 'φ'); // GREEK SMALL LETTER PHI
518        map.put(EXTENDED_KEYCODE_FLAG + 0x03C7, 'χ'); // GREEK SMALL LETTER CHI
519        map.put(EXTENDED_KEYCODE_FLAG + 0x03C8, 'ψ'); // GREEK SMALL LETTER PSI
520        map.put(EXTENDED_KEYCODE_FLAG + 0x03C9, 'ω'); // GREEK SMALL LETTER OMEGA
521    }
522
523    static void addCyrillicCharacters(Map<Integer, Character> map) {
524        map.put(EXTENDED_KEYCODE_FLAG + 0x0430, 'а'); // CYRILLIC SMALL LETTER A
525        map.put(EXTENDED_KEYCODE_FLAG + 0x0431, 'б'); // CYRILLIC SMALL LETTER BE
526        map.put(EXTENDED_KEYCODE_FLAG + 0x0432, 'в'); // CYRILLIC SMALL LETTER VE
527        map.put(EXTENDED_KEYCODE_FLAG + 0x0433, 'г'); // CYRILLIC SMALL LETTER GHE
528        map.put(EXTENDED_KEYCODE_FLAG + 0x0434, 'д'); // CYRILLIC SMALL LETTER DE
529        map.put(EXTENDED_KEYCODE_FLAG + 0x0435, 'е'); // CYRILLIC SMALL LETTER IE
530        map.put(EXTENDED_KEYCODE_FLAG + 0x0436, 'ж'); // CYRILLIC SMALL LETTER ZHE
531        map.put(EXTENDED_KEYCODE_FLAG + 0x0437, 'з'); // CYRILLIC SMALL LETTER ZE
532        map.put(EXTENDED_KEYCODE_FLAG + 0x0438, 'и'); // CYRILLIC SMALL LETTER I
533        map.put(EXTENDED_KEYCODE_FLAG + 0x0439, 'й'); // CYRILLIC SMALL LETTER SHORT I
534        map.put(EXTENDED_KEYCODE_FLAG + 0x043A, 'к'); // CYRILLIC SMALL LETTER KA
535        map.put(EXTENDED_KEYCODE_FLAG + 0x043B, 'л'); // CYRILLIC SMALL LETTER EL
536        map.put(EXTENDED_KEYCODE_FLAG + 0x043C, 'м'); // CYRILLIC SMALL LETTER EM
537        map.put(EXTENDED_KEYCODE_FLAG + 0x043D, 'н'); // CYRILLIC SMALL LETTER EN
538        map.put(EXTENDED_KEYCODE_FLAG + 0x043E, 'о'); // CYRILLIC SMALL LETTER O
539        map.put(EXTENDED_KEYCODE_FLAG + 0x043F, 'п'); // CYRILLIC SMALL LETTER PE
540        map.put(EXTENDED_KEYCODE_FLAG + 0x0440, 'р'); // CYRILLIC SMALL LETTER ER
541        map.put(EXTENDED_KEYCODE_FLAG + 0x0441, 'с'); // CYRILLIC SMALL LETTER ES
542        map.put(EXTENDED_KEYCODE_FLAG + 0x0442, 'т'); // CYRILLIC SMALL LETTER TE
543        map.put(EXTENDED_KEYCODE_FLAG + 0x0443, 'у'); // CYRILLIC SMALL LETTER U
544        map.put(EXTENDED_KEYCODE_FLAG + 0x0444, 'ф'); // CYRILLIC SMALL LETTER EF
545        map.put(EXTENDED_KEYCODE_FLAG + 0x0445, 'х'); // CYRILLIC SMALL LETTER HA
546        map.put(EXTENDED_KEYCODE_FLAG + 0x0446, 'ц'); // CYRILLIC SMALL LETTER TSE
547        map.put(EXTENDED_KEYCODE_FLAG + 0x0447, 'ч'); // CYRILLIC SMALL LETTER CHE
548        map.put(EXTENDED_KEYCODE_FLAG + 0x0448, 'ш'); // CYRILLIC SMALL LETTER SHA
549        map.put(EXTENDED_KEYCODE_FLAG + 0x0449, 'щ'); // CYRILLIC SMALL LETTER SHCHA
550        map.put(EXTENDED_KEYCODE_FLAG + 0x044A, 'ъ'); // CYRILLIC SMALL LETTER HARD SIGN
551        map.put(EXTENDED_KEYCODE_FLAG + 0x044B, 'ы'); // CYRILLIC SMALL LETTER YERU
552        map.put(EXTENDED_KEYCODE_FLAG + 0x044C, 'ь'); // CYRILLIC SMALL LETTER SOFT SIGN
553        map.put(EXTENDED_KEYCODE_FLAG + 0x044D, 'э'); // CYRILLIC SMALL LETTER E
554        map.put(EXTENDED_KEYCODE_FLAG + 0x044E, 'ю'); // CYRILLIC SMALL LETTER YU
555        map.put(EXTENDED_KEYCODE_FLAG + 0x044F, 'я'); // CYRILLIC SMALL LETTER YA
556        map.put(EXTENDED_KEYCODE_FLAG + 0x0451, 'ё'); // CYRILLIC SMALL LETTER IO
557        map.put(EXTENDED_KEYCODE_FLAG + 0x0452, 'ђ'); // CYRILLIC SMALL LETTER DJE
558        map.put(EXTENDED_KEYCODE_FLAG + 0x0453, 'ѓ'); // CYRILLIC SMALL LETTER GJE
559        map.put(EXTENDED_KEYCODE_FLAG + 0x0454, 'є'); // CYRILLIC SMALL LETTER UKRAINIAN IE
560        map.put(EXTENDED_KEYCODE_FLAG + 0x0455, 'ѕ'); // CYRILLIC SMALL LETTER DZE
561        map.put(EXTENDED_KEYCODE_FLAG + 0x0456, 'і'); // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
562        map.put(EXTENDED_KEYCODE_FLAG + 0x0457, 'ї'); // CYRILLIC SMALL LETTER YI
563        map.put(EXTENDED_KEYCODE_FLAG + 0x0458, 'ј'); // CYRILLIC SMALL LETTER JE
564        map.put(EXTENDED_KEYCODE_FLAG + 0x0459, 'љ'); // CYRILLIC SMALL LETTER LJE
565        map.put(EXTENDED_KEYCODE_FLAG + 0x045A, 'њ'); // CYRILLIC SMALL LETTER NJE
566        map.put(EXTENDED_KEYCODE_FLAG + 0x045B, 'ћ'); // CYRILLIC SMALL LETTER TSHE
567        map.put(EXTENDED_KEYCODE_FLAG + 0x045C, 'ќ'); // CYRILLIC SMALL LETTER KJE
568        map.put(EXTENDED_KEYCODE_FLAG + 0x045E, 'ў'); // CYRILLIC SMALL LETTER SHORT U
569        map.put(EXTENDED_KEYCODE_FLAG + 0x045F, 'џ'); // CYRILLIC SMALL LETTER DZHE
570        map.put(EXTENDED_KEYCODE_FLAG + 0x0491, 'ґ'); // CYRILLIC SMALL LETTER GHE WITH UPTURN
571        map.put(EXTENDED_KEYCODE_FLAG + 0x0493, 'ғ'); // CYRILLIC SMALL LETTER GHE WITH STROKE
572        map.put(EXTENDED_KEYCODE_FLAG + 0x0497, 'җ'); // CYRILLIC SMALL LETTER ZHE WITH DESCENDER
573        map.put(EXTENDED_KEYCODE_FLAG + 0x049B, 'қ'); // CYRILLIC SMALL LETTER KA WITH DESCENDER
574        map.put(EXTENDED_KEYCODE_FLAG + 0x049D, 'ҝ'); // CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE
575        map.put(EXTENDED_KEYCODE_FLAG + 0x04A3, 'ң'); // CYRILLIC SMALL LETTER EN WITH DESCENDER
576        map.put(EXTENDED_KEYCODE_FLAG + 0x04AF, 'ү'); // CYRILLIC SMALL LETTER STRAIGHT U
577        map.put(EXTENDED_KEYCODE_FLAG + 0x04B1, 'ұ'); // CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
578        map.put(EXTENDED_KEYCODE_FLAG + 0x04B3, 'ҳ'); // CYRILLIC SMALL LETTER HA WITH DESCENDER
579        map.put(EXTENDED_KEYCODE_FLAG + 0x04B9, 'ҹ'); // CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE
580        map.put(EXTENDED_KEYCODE_FLAG + 0x04BB, 'һ'); // CYRILLIC SMALL LETTER SHHA
581        map.put(EXTENDED_KEYCODE_FLAG + 0x04D9, 'ә'); // CYRILLIC SMALL LETTER SCHWA
582        map.put(EXTENDED_KEYCODE_FLAG + 0x04E9, 'ө'); // CYRILLIC SMALL LETTER BARRED O
583    }
584
585    static void addArmenianCharacters(Map<Integer, Character> map) {
586        map.put(EXTENDED_KEYCODE_FLAG + 0x055A, '՚'); // ARMENIAN APOSTROPHE
587        map.put(EXTENDED_KEYCODE_FLAG + 0x055B, '՛'); // ARMENIAN EMPHASIS MARK
588        map.put(EXTENDED_KEYCODE_FLAG + 0x055C, '՜'); // ARMENIAN EXCLAMATION MARK
589        map.put(EXTENDED_KEYCODE_FLAG + 0x055D, '՝'); // ARMENIAN COMMA
590        map.put(EXTENDED_KEYCODE_FLAG + 0x055E, '՞'); // ARMENIAN QUESTION MARK
591        map.put(EXTENDED_KEYCODE_FLAG + 0x055F, '՟'); // ARMENIAN ABBREVIATION MARK
592        map.put(EXTENDED_KEYCODE_FLAG + 0x0561, 'ա'); // ARMENIAN SMALL LETTER AYB
593        map.put(EXTENDED_KEYCODE_FLAG + 0x0562, 'բ'); // ARMENIAN SMALL LETTER BEN
594        map.put(EXTENDED_KEYCODE_FLAG + 0x0563, 'գ'); // ARMENIAN SMALL LETTER GIM
595        map.put(EXTENDED_KEYCODE_FLAG + 0x0564, 'դ'); // ARMENIAN SMALL LETTER DA
596        map.put(EXTENDED_KEYCODE_FLAG + 0x0565, 'ե'); // ARMENIAN SMALL LETTER ECH
597        map.put(EXTENDED_KEYCODE_FLAG + 0x0566, 'զ'); // ARMENIAN SMALL LETTER ZA
598        map.put(EXTENDED_KEYCODE_FLAG + 0x0567, 'է'); // ARMENIAN SMALL LETTER EH
599        map.put(EXTENDED_KEYCODE_FLAG + 0x0568, 'ը'); // ARMENIAN SMALL LETTER ET
600        map.put(EXTENDED_KEYCODE_FLAG + 0x0569, 'թ'); // ARMENIAN SMALL LETTER TO
601        map.put(EXTENDED_KEYCODE_FLAG + 0x056A, 'ժ'); // ARMENIAN SMALL LETTER ZHE
602        map.put(EXTENDED_KEYCODE_FLAG + 0x056B, 'ի'); // ARMENIAN SMALL LETTER INI
603        map.put(EXTENDED_KEYCODE_FLAG + 0x056C, 'լ'); // ARMENIAN SMALL LETTER LIWN
604        map.put(EXTENDED_KEYCODE_FLAG + 0x056D, 'խ'); // ARMENIAN SMALL LETTER XEH
605        map.put(EXTENDED_KEYCODE_FLAG + 0x056E, 'ծ'); // ARMENIAN SMALL LETTER CA
606        map.put(EXTENDED_KEYCODE_FLAG + 0x056F, 'կ'); // ARMENIAN SMALL LETTER KEN
607        map.put(EXTENDED_KEYCODE_FLAG + 0x0570, 'հ'); // ARMENIAN SMALL LETTER HO
608        map.put(EXTENDED_KEYCODE_FLAG + 0x0571, 'ձ'); // ARMENIAN SMALL LETTER JA
609        map.put(EXTENDED_KEYCODE_FLAG + 0x0572, 'ղ'); // ARMENIAN SMALL LETTER GHAD
610        map.put(EXTENDED_KEYCODE_FLAG + 0x0573, 'ճ'); // ARMENIAN SMALL LETTER CHEH
611        map.put(EXTENDED_KEYCODE_FLAG + 0x0574, 'մ'); // ARMENIAN SMALL LETTER MEN
612        map.put(EXTENDED_KEYCODE_FLAG + 0x0575, 'յ'); // ARMENIAN SMALL LETTER YI
613        map.put(EXTENDED_KEYCODE_FLAG + 0x0576, 'ն'); // ARMENIAN SMALL LETTER NOW
614        map.put(EXTENDED_KEYCODE_FLAG + 0x0577, 'շ'); // ARMENIAN SMALL LETTER SHA
615        map.put(EXTENDED_KEYCODE_FLAG + 0x0578, 'ո'); // ARMENIAN SMALL LETTER VO
616        map.put(EXTENDED_KEYCODE_FLAG + 0x0579, 'չ'); // ARMENIAN SMALL LETTER CHA
617        map.put(EXTENDED_KEYCODE_FLAG + 0x057A, 'պ'); // ARMENIAN SMALL LETTER PEH
618        map.put(EXTENDED_KEYCODE_FLAG + 0x057B, 'ջ'); // ARMENIAN SMALL LETTER JHEH
619        map.put(EXTENDED_KEYCODE_FLAG + 0x057C, 'ռ'); // ARMENIAN SMALL LETTER RA
620        map.put(EXTENDED_KEYCODE_FLAG + 0x057D, 'ս'); // ARMENIAN SMALL LETTER SEH
621        map.put(EXTENDED_KEYCODE_FLAG + 0x057E, 'վ'); // ARMENIAN SMALL LETTER VEW
622        map.put(EXTENDED_KEYCODE_FLAG + 0x057F, 'տ'); // ARMENIAN SMALL LETTER TIWN
623        map.put(EXTENDED_KEYCODE_FLAG + 0x0580, 'ր'); // ARMENIAN SMALL LETTER REH
624        map.put(EXTENDED_KEYCODE_FLAG + 0x0581, 'ց'); // ARMENIAN SMALL LETTER CO
625        map.put(EXTENDED_KEYCODE_FLAG + 0x0582, 'ւ'); // ARMENIAN SMALL LETTER YIWN
626        map.put(EXTENDED_KEYCODE_FLAG + 0x0583, 'փ'); // ARMENIAN SMALL LETTER PIWR
627        map.put(EXTENDED_KEYCODE_FLAG + 0x0584, 'ք'); // ARMENIAN SMALL LETTER KEH
628        map.put(EXTENDED_KEYCODE_FLAG + 0x0585, 'օ'); // ARMENIAN SMALL LETTER OH
629        map.put(EXTENDED_KEYCODE_FLAG + 0x0586, 'ֆ'); // ARMENIAN SMALL LETTER FEH
630        map.put(EXTENDED_KEYCODE_FLAG + 0x0587, 'և'); // ARMENIAN SMALL LIGATURE ECH YIWN
631        map.put(EXTENDED_KEYCODE_FLAG + 0x0589, '։'); // ARMENIAN FULL STOP
632    }
633
634    static void addHebrewCharacters(Map<Integer, Character> map) {
635        map.put(EXTENDED_KEYCODE_FLAG + 0x05D0, 'א'); // HEBREW LETTER ALEF
636        map.put(EXTENDED_KEYCODE_FLAG + 0x05D1, 'ב'); // HEBREW LETTER BET
637        map.put(EXTENDED_KEYCODE_FLAG + 0x05D2, 'ג'); // HEBREW LETTER GIMEL
638        map.put(EXTENDED_KEYCODE_FLAG + 0x05D3, 'ד'); // HEBREW LETTER DALET
639        map.put(EXTENDED_KEYCODE_FLAG + 0x05D4, 'ה'); // HEBREW LETTER HE
640        map.put(EXTENDED_KEYCODE_FLAG + 0x05D5, 'ו'); // HEBREW LETTER VAV
641        map.put(EXTENDED_KEYCODE_FLAG + 0x05D6, 'ז'); // HEBREW LETTER ZAYIN
642        map.put(EXTENDED_KEYCODE_FLAG + 0x05D7, 'ח'); // HEBREW LETTER HET
643        map.put(EXTENDED_KEYCODE_FLAG + 0x05D8, 'ט'); // HEBREW LETTER TET
644        map.put(EXTENDED_KEYCODE_FLAG + 0x05D9, 'י'); // HEBREW LETTER YOD
645        map.put(EXTENDED_KEYCODE_FLAG + 0x05DA, 'ך'); // HEBREW LETTER FINAL KAF
646        map.put(EXTENDED_KEYCODE_FLAG + 0x05DB, 'כ'); // HEBREW LETTER KAF
647        map.put(EXTENDED_KEYCODE_FLAG + 0x05DC, 'ל'); // HEBREW LETTER LAMED
648        map.put(EXTENDED_KEYCODE_FLAG + 0x05DD, 'ם'); // HEBREW LETTER FINAL MEM
649        map.put(EXTENDED_KEYCODE_FLAG + 0x05DE, 'מ'); // HEBREW LETTER MEM
650        map.put(EXTENDED_KEYCODE_FLAG + 0x05DF, 'ן'); // HEBREW LETTER FINAL NUN
651        map.put(EXTENDED_KEYCODE_FLAG + 0x05E0, 'נ'); // HEBREW LETTER NUN
652        map.put(EXTENDED_KEYCODE_FLAG + 0x05E1, 'ס'); // HEBREW LETTER SAMEKH
653        map.put(EXTENDED_KEYCODE_FLAG + 0x05E2, 'ע'); // HEBREW LETTER AYIN
654        map.put(EXTENDED_KEYCODE_FLAG + 0x05E3, 'ף'); // HEBREW LETTER FINAL PE
655        map.put(EXTENDED_KEYCODE_FLAG + 0x05E4, 'פ'); // HEBREW LETTER PE
656        map.put(EXTENDED_KEYCODE_FLAG + 0x05E5, 'ץ'); // HEBREW LETTER FINAL TSADI
657        map.put(EXTENDED_KEYCODE_FLAG + 0x05E6, 'צ'); // HEBREW LETTER TSADI
658        map.put(EXTENDED_KEYCODE_FLAG + 0x05E7, 'ק'); // HEBREW LETTER QOF
659        map.put(EXTENDED_KEYCODE_FLAG + 0x05E8, 'ר'); // HEBREW LETTER RESH
660        map.put(EXTENDED_KEYCODE_FLAG + 0x05E9, 'ש'); // HEBREW LETTER SHIN
661        map.put(EXTENDED_KEYCODE_FLAG + 0x05EA, 'ת'); // HEBREW LETTER TAV
662    }
663
664    static void addArabicCharacters(Map<Integer, Character> map) {
665        map.put(EXTENDED_KEYCODE_FLAG + 0x060C, '،'); // ARABIC COMMA
666        map.put(EXTENDED_KEYCODE_FLAG + 0x061B, '؛'); // ARABIC SEMICOLON
667        map.put(EXTENDED_KEYCODE_FLAG + 0x0621, 'ء'); // ARABIC LETTER HAMZA
668        map.put(EXTENDED_KEYCODE_FLAG + 0x0624, 'ؤ'); // ARABIC LETTER WAW WITH HAMZA ABOVE
669        map.put(EXTENDED_KEYCODE_FLAG + 0x0626, 'ئ'); // ARABIC LETTER YEH WITH HAMZA ABOVE
670        map.put(EXTENDED_KEYCODE_FLAG + 0x0627, 'ا'); // ARABIC LETTER ALEF
671        map.put(EXTENDED_KEYCODE_FLAG + 0x0628, 'ب'); // ARABIC LETTER BEH
672        map.put(EXTENDED_KEYCODE_FLAG + 0x0629, 'ة'); // ARABIC LETTER TEH MARBUTA
673        map.put(EXTENDED_KEYCODE_FLAG + 0x062A, 'ت'); // ARABIC LETTER TEH
674        map.put(EXTENDED_KEYCODE_FLAG + 0x062B, 'ث'); // ARABIC LETTER THEH
675        map.put(EXTENDED_KEYCODE_FLAG + 0x062C, 'ج'); // ARABIC LETTER JEEM
676        map.put(EXTENDED_KEYCODE_FLAG + 0x062D, 'ح'); // ARABIC LETTER HAH
677        map.put(EXTENDED_KEYCODE_FLAG + 0x062E, 'خ'); // ARABIC LETTER KHAH
678        map.put(EXTENDED_KEYCODE_FLAG + 0x062F, 'د'); // ARABIC LETTER DAL
679        map.put(EXTENDED_KEYCODE_FLAG + 0x0630, 'ذ'); // ARABIC LETTER THAL
680        map.put(EXTENDED_KEYCODE_FLAG + 0x0631, 'ر'); // ARABIC LETTER REH
681        map.put(EXTENDED_KEYCODE_FLAG + 0x0632, 'ز'); // ARABIC LETTER ZAIN
682        map.put(EXTENDED_KEYCODE_FLAG + 0x0633, 'س'); // ARABIC LETTER SEEN
683        map.put(EXTENDED_KEYCODE_FLAG + 0x0634, 'ش'); // ARABIC LETTER SHEEN
684        map.put(EXTENDED_KEYCODE_FLAG + 0x0635, 'ص'); // ARABIC LETTER SAD
685        map.put(EXTENDED_KEYCODE_FLAG + 0x0636, 'ض'); // ARABIC LETTER DAD
686        map.put(EXTENDED_KEYCODE_FLAG + 0x0637, 'ط'); // ARABIC LETTER TAH
687        map.put(EXTENDED_KEYCODE_FLAG + 0x0638, 'ظ'); // ARABIC LETTER ZAH
688        map.put(EXTENDED_KEYCODE_FLAG + 0x0639, 'ع'); // ARABIC LETTER AIN
689        map.put(EXTENDED_KEYCODE_FLAG + 0x063A, 'غ'); // ARABIC LETTER GHAIN
690        map.put(EXTENDED_KEYCODE_FLAG + 0x0641, 'ف'); // ARABIC LETTER FEH
691        map.put(EXTENDED_KEYCODE_FLAG + 0x0642, 'ق'); // ARABIC LETTER QAF
692        map.put(EXTENDED_KEYCODE_FLAG + 0x0643, 'ك'); // ARABIC LETTER KAF
693        map.put(EXTENDED_KEYCODE_FLAG + 0x0644, 'ل'); // ARABIC LETTER LAM
694        map.put(EXTENDED_KEYCODE_FLAG + 0x0645, 'م'); // ARABIC LETTER MEEM
695        map.put(EXTENDED_KEYCODE_FLAG + 0x0646, 'ن'); // ARABIC LETTER NOON
696        map.put(EXTENDED_KEYCODE_FLAG + 0x0647, 'ه'); // ARABIC LETTER HEH
697        map.put(EXTENDED_KEYCODE_FLAG + 0x0648, 'و'); // ARABIC LETTER WAW
698        map.put(EXTENDED_KEYCODE_FLAG + 0x0649, 'ى'); // ARABIC LETTER ALEF MAKSURA
699        map.put(EXTENDED_KEYCODE_FLAG + 0x064A, 'ي'); // ARABIC LETTER YEH
700        map.put(EXTENDED_KEYCODE_FLAG + 0x064E, 'َ'); // ARABIC FATHA
701        map.put(EXTENDED_KEYCODE_FLAG + 0x064F, 'ُ'); // ARABIC DAMMA
702        map.put(EXTENDED_KEYCODE_FLAG + 0x0650, 'ِ'); // ARABIC KASRA
703        map.put(EXTENDED_KEYCODE_FLAG + 0x0652, 'ْ'); // ARABIC SUKUN
704        map.put(EXTENDED_KEYCODE_FLAG + 0x0660, '٠'); // ARABIC-INDIC DIGIT ZERO
705        map.put(EXTENDED_KEYCODE_FLAG + 0x0661, '١'); // ARABIC-INDIC DIGIT ONE
706        map.put(EXTENDED_KEYCODE_FLAG + 0x0662, '٢'); // ARABIC-INDIC DIGIT TWO
707        map.put(EXTENDED_KEYCODE_FLAG + 0x0663, '٣'); // ARABIC-INDIC DIGIT THREE
708        map.put(EXTENDED_KEYCODE_FLAG + 0x0664, '٤'); // ARABIC-INDIC DIGIT FOUR
709        map.put(EXTENDED_KEYCODE_FLAG + 0x0665, '٥'); // ARABIC-INDIC DIGIT FIVE
710        map.put(EXTENDED_KEYCODE_FLAG + 0x0666, '٦'); // ARABIC-INDIC DIGIT SIX
711        map.put(EXTENDED_KEYCODE_FLAG + 0x0667, '٧'); // ARABIC-INDIC DIGIT SEVEN
712        map.put(EXTENDED_KEYCODE_FLAG + 0x0668, '٨'); // ARABIC-INDIC DIGIT EIGHT
713        map.put(EXTENDED_KEYCODE_FLAG + 0x0669, '٩'); // ARABIC-INDIC DIGIT NINE
714        map.put(EXTENDED_KEYCODE_FLAG + 0x0670, 'ٰ'); // ARABIC LETTER SUPERSCRIPT ALEF
715        map.put(EXTENDED_KEYCODE_FLAG + 0x067E, 'پ'); // ARABIC LETTER PEH
716        map.put(EXTENDED_KEYCODE_FLAG + 0x0686, 'چ'); // ARABIC LETTER TCHEH
717        map.put(EXTENDED_KEYCODE_FLAG + 0x0698, 'ژ'); // ARABIC LETTER JEH
718        map.put(EXTENDED_KEYCODE_FLAG + 0x06A4, 'ڤ'); // ARABIC LETTER VEH
719        map.put(EXTENDED_KEYCODE_FLAG + 0x06A9, 'ک'); // ARABIC LETTER KEHEH
720        map.put(EXTENDED_KEYCODE_FLAG + 0x06AF, 'گ'); // ARABIC LETTER GAF
721        map.put(EXTENDED_KEYCODE_FLAG + 0x06BE, 'ھ'); // ARABIC LETTER HEH DOACHASHMEE
722        map.put(EXTENDED_KEYCODE_FLAG + 0x06CC, 'ی'); // ARABIC LETTER FARSI YEH
723        map.put(EXTENDED_KEYCODE_FLAG + 0x06D2, 'ے'); // ARABIC LETTER YEH BARREE
724        map.put(EXTENDED_KEYCODE_FLAG + 0x06D4, '۔'); // ARABIC FULL STOP
725        map.put(EXTENDED_KEYCODE_FLAG + 0x06F0, '۰'); // EXTENDED ARABIC-INDIC DIGIT ZERO
726        map.put(EXTENDED_KEYCODE_FLAG + 0x06F1, '۱'); // EXTENDED ARABIC-INDIC DIGIT ONE
727        map.put(EXTENDED_KEYCODE_FLAG + 0x06F2, '۲'); // EXTENDED ARABIC-INDIC DIGIT TWO
728        map.put(EXTENDED_KEYCODE_FLAG + 0x06F3, '۳'); // EXTENDED ARABIC-INDIC DIGIT THREE
729        map.put(EXTENDED_KEYCODE_FLAG + 0x06F4, '۴'); // EXTENDED ARABIC-INDIC DIGIT FOUR
730        map.put(EXTENDED_KEYCODE_FLAG + 0x06F5, '۵'); // EXTENDED ARABIC-INDIC DIGIT FIVE
731        map.put(EXTENDED_KEYCODE_FLAG + 0x06F6, '۶'); // EXTENDED ARABIC-INDIC DIGIT SIX
732        map.put(EXTENDED_KEYCODE_FLAG + 0x06F7, '۷'); // EXTENDED ARABIC-INDIC DIGIT SEVEN
733        map.put(EXTENDED_KEYCODE_FLAG + 0x06F8, '۸'); // EXTENDED ARABIC-INDIC DIGIT EIGHT
734        map.put(EXTENDED_KEYCODE_FLAG + 0x06F9, '۹'); // EXTENDED ARABIC-INDIC DIGIT NINE
735    }
736
737    static void addThaiCharacters(Map<Integer, Character> map) {
738        map.put(EXTENDED_KEYCODE_FLAG + 0x0E01, 'ก'); // THAI CHARACTER KO KAI
739        map.put(EXTENDED_KEYCODE_FLAG + 0x0E02, 'ข'); // THAI CHARACTER KHO KHAI
740        map.put(EXTENDED_KEYCODE_FLAG + 0x0E03, 'ฃ'); // THAI CHARACTER KHO KHUAT
741        map.put(EXTENDED_KEYCODE_FLAG + 0x0E04, 'ค'); // THAI CHARACTER KHO KHWAI
742        map.put(EXTENDED_KEYCODE_FLAG + 0x0E05, 'ฅ'); // THAI CHARACTER KHO KHON
743        map.put(EXTENDED_KEYCODE_FLAG + 0x0E07, 'ง'); // THAI CHARACTER NGO NGU
744        map.put(EXTENDED_KEYCODE_FLAG + 0x0E08, 'จ'); // THAI CHARACTER CHO CHAN
745        map.put(EXTENDED_KEYCODE_FLAG + 0x0E0A, 'ช'); // THAI CHARACTER CHO CHANG
746        map.put(EXTENDED_KEYCODE_FLAG + 0x0E0C, 'ฌ'); // THAI CHARACTER CHO CHOE
747        map.put(EXTENDED_KEYCODE_FLAG + 0x0E14, 'ด'); // THAI CHARACTER DO DEK
748        map.put(EXTENDED_KEYCODE_FLAG + 0x0E15, 'ต'); // THAI CHARACTER TO TAO
749        map.put(EXTENDED_KEYCODE_FLAG + 0x0E16, 'ถ'); // THAI CHARACTER THO THUNG
750        map.put(EXTENDED_KEYCODE_FLAG + 0x0E17, 'ท'); // THAI CHARACTER THO THAHAN
751        map.put(EXTENDED_KEYCODE_FLAG + 0x0E19, 'น'); // THAI CHARACTER NO NU
752        map.put(EXTENDED_KEYCODE_FLAG + 0x0E1A, 'บ'); // THAI CHARACTER BO BAIMAI
753        map.put(EXTENDED_KEYCODE_FLAG + 0x0E1B, 'ป'); // THAI CHARACTER PO PLA
754        map.put(EXTENDED_KEYCODE_FLAG + 0x0E1C, 'ผ'); // THAI CHARACTER PHO PHUNG
755        map.put(EXTENDED_KEYCODE_FLAG + 0x0E1D, 'ฝ'); // THAI CHARACTER FO FA
756        map.put(EXTENDED_KEYCODE_FLAG + 0x0E1E, 'พ'); // THAI CHARACTER PHO PHAN
757        map.put(EXTENDED_KEYCODE_FLAG + 0x0E1F, 'ฟ'); // THAI CHARACTER FO FAN
758        map.put(EXTENDED_KEYCODE_FLAG + 0x0E20, 'ภ'); // THAI CHARACTER PHO SAMPHAO
759        map.put(EXTENDED_KEYCODE_FLAG + 0x0E21, 'ม'); // THAI CHARACTER MO MA
760        map.put(EXTENDED_KEYCODE_FLAG + 0x0E22, 'ย'); // THAI CHARACTER YO YAK
761        map.put(EXTENDED_KEYCODE_FLAG + 0x0E23, 'ร'); // THAI CHARACTER RO RUA
762        map.put(EXTENDED_KEYCODE_FLAG + 0x0E25, 'ล'); // THAI CHARACTER LO LING
763        map.put(EXTENDED_KEYCODE_FLAG + 0x0E27, 'ว'); // THAI CHARACTER WO WAEN
764        map.put(EXTENDED_KEYCODE_FLAG + 0x0E2A, 'ส'); // THAI CHARACTER SO SUA
765        map.put(EXTENDED_KEYCODE_FLAG + 0x0E2B, 'ห'); // THAI CHARACTER HO HIP
766        map.put(EXTENDED_KEYCODE_FLAG + 0x0E2D, 'อ'); // THAI CHARACTER O ANG
767        map.put(EXTENDED_KEYCODE_FLAG + 0x0E30, 'ะ'); // THAI CHARACTER SARA A
768        map.put(EXTENDED_KEYCODE_FLAG + 0x0E31, 'ั'); // THAI CHARACTER MAI HAN-AKAT
769        map.put(EXTENDED_KEYCODE_FLAG + 0x0E32, 'า'); // THAI CHARACTER SARA AA
770        map.put(EXTENDED_KEYCODE_FLAG + 0x0E33, 'ำ'); // THAI CHARACTER SARA AM
771        map.put(EXTENDED_KEYCODE_FLAG + 0x0E34, 'ิ'); // THAI CHARACTER SARA I
772        map.put(EXTENDED_KEYCODE_FLAG + 0x0E35, 'ี'); // THAI CHARACTER SARA II
773        map.put(EXTENDED_KEYCODE_FLAG + 0x0E36, 'ึ'); // THAI CHARACTER SARA UE
774        map.put(EXTENDED_KEYCODE_FLAG + 0x0E37, 'ื'); // THAI CHARACTER SARA UEE
775        map.put(EXTENDED_KEYCODE_FLAG + 0x0E38, 'ุ'); // THAI CHARACTER SARA U
776        map.put(EXTENDED_KEYCODE_FLAG + 0x0E39, 'ู'); // THAI CHARACTER SARA UU
777        map.put(EXTENDED_KEYCODE_FLAG + 0x0E3F, '฿'); // THAI CURRENCY SYMBOL BAHT
778        map.put(EXTENDED_KEYCODE_FLAG + 0x0E40, 'เ'); // THAI CHARACTER SARA E
779        map.put(EXTENDED_KEYCODE_FLAG + 0x0E41, 'แ'); // THAI CHARACTER SARA AE
780        map.put(EXTENDED_KEYCODE_FLAG + 0x0E43, 'ใ'); // THAI CHARACTER SARA AI MAIMUAN
781        map.put(EXTENDED_KEYCODE_FLAG + 0x0E44, 'ไ'); // THAI CHARACTER SARA AI MAIMALAI
782        map.put(EXTENDED_KEYCODE_FLAG + 0x0E45, 'ๅ'); // THAI CHARACTER LAKKHANGYAO
783        map.put(EXTENDED_KEYCODE_FLAG + 0x0E46, 'ๆ'); // THAI CHARACTER MAIYAMOK
784        map.put(EXTENDED_KEYCODE_FLAG + 0x0E47, '็'); // THAI CHARACTER MAITAIKHU
785        map.put(EXTENDED_KEYCODE_FLAG + 0x0E48, '่'); // THAI CHARACTER MAI EK
786        map.put(EXTENDED_KEYCODE_FLAG + 0x0E49, '้'); // THAI CHARACTER MAI THO
787        map.put(EXTENDED_KEYCODE_FLAG + 0x0E50, '๐'); // THAI DIGIT ZERO
788        map.put(EXTENDED_KEYCODE_FLAG + 0x0E51, '๑'); // THAI DIGIT ONE
789        map.put(EXTENDED_KEYCODE_FLAG + 0x0E52, '๒'); // THAI DIGIT TWO
790        map.put(EXTENDED_KEYCODE_FLAG + 0x0E53, '๓'); // THAI DIGIT THREE
791        map.put(EXTENDED_KEYCODE_FLAG + 0x0E54, '๔'); // THAI DIGIT FOUR
792        map.put(EXTENDED_KEYCODE_FLAG + 0x0E55, '๕'); // THAI DIGIT FIVE
793        map.put(EXTENDED_KEYCODE_FLAG + 0x0E56, '๖'); // THAI DIGIT SIX
794        map.put(EXTENDED_KEYCODE_FLAG + 0x0E57, '๗'); // THAI DIGIT SEVEN
795        map.put(EXTENDED_KEYCODE_FLAG + 0x0E58, '๘'); // THAI DIGIT EIGHT
796        map.put(EXTENDED_KEYCODE_FLAG + 0x0E59, '๙'); // THAI DIGIT NINE
797    }
798
799    static void addGeorgianCharacters(Map<Integer, Character> map) {
800        map.put(EXTENDED_KEYCODE_FLAG + 0x10D0, 'ა'); // GEORGIAN LETTER AN
801        map.put(EXTENDED_KEYCODE_FLAG + 0x10D1, 'ბ'); // GEORGIAN LETTER BAN
802        map.put(EXTENDED_KEYCODE_FLAG + 0x10D2, 'გ'); // GEORGIAN LETTER GAN
803        map.put(EXTENDED_KEYCODE_FLAG + 0x10D3, 'დ'); // GEORGIAN LETTER DON
804        map.put(EXTENDED_KEYCODE_FLAG + 0x10D4, 'ე'); // GEORGIAN LETTER EN
805        map.put(EXTENDED_KEYCODE_FLAG + 0x10D5, 'ვ'); // GEORGIAN LETTER VIN
806        map.put(EXTENDED_KEYCODE_FLAG + 0x10D6, 'ზ'); // GEORGIAN LETTER ZEN
807        map.put(EXTENDED_KEYCODE_FLAG + 0x10D7, 'თ'); // GEORGIAN LETTER TAN
808        map.put(EXTENDED_KEYCODE_FLAG + 0x10D8, 'ი'); // GEORGIAN LETTER IN
809        map.put(EXTENDED_KEYCODE_FLAG + 0x10D9, 'კ'); // GEORGIAN LETTER KAN
810        map.put(EXTENDED_KEYCODE_FLAG + 0x10DA, 'ლ'); // GEORGIAN LETTER LAS
811        map.put(EXTENDED_KEYCODE_FLAG + 0x10DB, 'მ'); // GEORGIAN LETTER MAN
812        map.put(EXTENDED_KEYCODE_FLAG + 0x10DC, 'ნ'); // GEORGIAN LETTER NAR
813        map.put(EXTENDED_KEYCODE_FLAG + 0x10DD, 'ო'); // GEORGIAN LETTER ON
814        map.put(EXTENDED_KEYCODE_FLAG + 0x10DE, 'პ'); // GEORGIAN LETTER PAR
815        map.put(EXTENDED_KEYCODE_FLAG + 0x10DF, 'ჟ'); // GEORGIAN LETTER ZHAR
816        map.put(EXTENDED_KEYCODE_FLAG + 0x10E0, 'რ'); // GEORGIAN LETTER RAE
817        map.put(EXTENDED_KEYCODE_FLAG + 0x10E1, 'ს'); // GEORGIAN LETTER SAN
818        map.put(EXTENDED_KEYCODE_FLAG + 0x10E2, 'ტ'); // GEORGIAN LETTER TAR
819        map.put(EXTENDED_KEYCODE_FLAG + 0x10E3, 'უ'); // GEORGIAN LETTER UN
820        map.put(EXTENDED_KEYCODE_FLAG + 0x10E4, 'ფ'); // GEORGIAN LETTER PHAR
821        map.put(EXTENDED_KEYCODE_FLAG + 0x10E5, 'ქ'); // GEORGIAN LETTER KHAR
822        map.put(EXTENDED_KEYCODE_FLAG + 0x10E6, 'ღ'); // GEORGIAN LETTER GHAN
823        map.put(EXTENDED_KEYCODE_FLAG + 0x10E7, 'ყ'); // GEORGIAN LETTER QAR
824        map.put(EXTENDED_KEYCODE_FLAG + 0x10E8, 'შ'); // GEORGIAN LETTER SHIN
825        map.put(EXTENDED_KEYCODE_FLAG + 0x10E9, 'ჩ'); // GEORGIAN LETTER CHIN
826        map.put(EXTENDED_KEYCODE_FLAG + 0x10EA, 'ც'); // GEORGIAN LETTER CAN
827        map.put(EXTENDED_KEYCODE_FLAG + 0x10EB, 'ძ'); // GEORGIAN LETTER JIL
828        map.put(EXTENDED_KEYCODE_FLAG + 0x10EC, 'წ'); // GEORGIAN LETTER CIL
829        map.put(EXTENDED_KEYCODE_FLAG + 0x10ED, 'ჭ'); // GEORGIAN LETTER CHAR
830        map.put(EXTENDED_KEYCODE_FLAG + 0x10EE, 'ხ'); // GEORGIAN LETTER XAN
831        map.put(EXTENDED_KEYCODE_FLAG + 0x10EF, 'ჯ'); // GEORGIAN LETTER JHAN
832        map.put(EXTENDED_KEYCODE_FLAG + 0x10F0, 'ჰ'); // GEORGIAN LETTER HAE
833    }
834
835    static void addSymbolCharacters(Map<Integer, Character> map) {
836        map.put(EXTENDED_KEYCODE_FLAG + 0x2013, '–'); // EN DASH
837        map.put(EXTENDED_KEYCODE_FLAG + 0x2015, '―'); // HORIZONTAL BAR
838        map.put(EXTENDED_KEYCODE_FLAG + 0x201C, '“'); // LEFT DOUBLE QUOTATION MARK
839        map.put(EXTENDED_KEYCODE_FLAG + 0x201D, '”'); // RIGHT DOUBLE QUOTATION MARK
840        map.put(EXTENDED_KEYCODE_FLAG + 0x201E, '„'); // DOUBLE LOW-9 QUOTATION MARK
841        map.put(EXTENDED_KEYCODE_FLAG + 0x20AB, '₫'); // DONG SIGN
842        map.put(EXTENDED_KEYCODE_FLAG + 0x2116, '№'); // NUMERO SIGN
843        map.put(EXTENDED_KEYCODE_FLAG + 0x2190, '←'); // LEFTWARDS ARROW
844        map.put(EXTENDED_KEYCODE_FLAG + 0x2191, '↑'); // UPWARDS ARROW
845        map.put(EXTENDED_KEYCODE_FLAG + 0x2192, '→'); // RIGHTWARDS ARROW
846        map.put(EXTENDED_KEYCODE_FLAG + 0x2193, '↓'); // DOWNWARDS ARROW
847    }
848
849    static void addJapaneseCharacters(Map<Integer, Character> map) {
850        map.put(EXTENDED_KEYCODE_FLAG + 0x309B, '゛'); // KATAKANA-HIRAGANA VOICED SOUND MARK
851        map.put(EXTENDED_KEYCODE_FLAG + 0x309C, '゜'); // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
852        map.put(EXTENDED_KEYCODE_FLAG + 0x30A2, 'ア'); // KATAKANA LETTER A
853        map.put(EXTENDED_KEYCODE_FLAG + 0x30A4, 'イ'); // KATAKANA LETTER I
854        map.put(EXTENDED_KEYCODE_FLAG + 0x30A6, 'ウ'); // KATAKANA LETTER U
855        map.put(EXTENDED_KEYCODE_FLAG + 0x30A8, 'エ'); // KATAKANA LETTER E
856        map.put(EXTENDED_KEYCODE_FLAG + 0x30AA, 'オ'); // KATAKANA LETTER O
857        map.put(EXTENDED_KEYCODE_FLAG + 0x30AB, 'カ'); // KATAKANA LETTER KA
858        map.put(EXTENDED_KEYCODE_FLAG + 0x30AD, 'キ'); // KATAKANA LETTER KI
859        map.put(EXTENDED_KEYCODE_FLAG + 0x30AF, 'ク'); // KATAKANA LETTER KU
860        map.put(EXTENDED_KEYCODE_FLAG + 0x30B1, 'ケ'); // KATAKANA LETTER KE
861        map.put(EXTENDED_KEYCODE_FLAG + 0x30B3, 'コ'); // KATAKANA LETTER KO
862        map.put(EXTENDED_KEYCODE_FLAG + 0x30B5, 'サ'); // KATAKANA LETTER SA
863        map.put(EXTENDED_KEYCODE_FLAG + 0x30B7, 'シ'); // KATAKANA LETTER SI
864        map.put(EXTENDED_KEYCODE_FLAG + 0x30B9, 'ス'); // KATAKANA LETTER SU
865        map.put(EXTENDED_KEYCODE_FLAG + 0x30BB, 'セ'); // KATAKANA LETTER SE
866        map.put(EXTENDED_KEYCODE_FLAG + 0x30BD, 'ソ'); // KATAKANA LETTER SO
867        map.put(EXTENDED_KEYCODE_FLAG + 0x30BF, 'タ'); // KATAKANA LETTER TA
868        map.put(EXTENDED_KEYCODE_FLAG + 0x30C1, 'チ'); // KATAKANA LETTER TI
869        map.put(EXTENDED_KEYCODE_FLAG + 0x30C4, 'ツ'); // KATAKANA LETTER TU
870        map.put(EXTENDED_KEYCODE_FLAG + 0x30C6, 'テ'); // KATAKANA LETTER TE
871        map.put(EXTENDED_KEYCODE_FLAG + 0x30C8, 'ト'); // KATAKANA LETTER TO
872        map.put(EXTENDED_KEYCODE_FLAG + 0x30CA, 'ナ'); // KATAKANA LETTER NA
873        map.put(EXTENDED_KEYCODE_FLAG + 0x30CB, 'ニ'); // KATAKANA LETTER NI
874        map.put(EXTENDED_KEYCODE_FLAG + 0x30CC, 'ヌ'); // KATAKANA LETTER NU
875        map.put(EXTENDED_KEYCODE_FLAG + 0x30CD, 'ネ'); // KATAKANA LETTER NE
876        map.put(EXTENDED_KEYCODE_FLAG + 0x30CE, 'ノ'); // KATAKANA LETTER NO
877        map.put(EXTENDED_KEYCODE_FLAG + 0x30CF, 'ハ'); // KATAKANA LETTER HA
878        map.put(EXTENDED_KEYCODE_FLAG + 0x30D2, 'ヒ'); // KATAKANA LETTER HI
879        map.put(EXTENDED_KEYCODE_FLAG + 0x30D5, 'フ'); // KATAKANA LETTER HU
880        map.put(EXTENDED_KEYCODE_FLAG + 0x30D8, 'ヘ'); // KATAKANA LETTER HE
881        map.put(EXTENDED_KEYCODE_FLAG + 0x30DB, 'ホ'); // KATAKANA LETTER HO
882        map.put(EXTENDED_KEYCODE_FLAG + 0x30DE, 'マ'); // KATAKANA LETTER MA
883        map.put(EXTENDED_KEYCODE_FLAG + 0x30DF, 'ミ'); // KATAKANA LETTER MI
884        map.put(EXTENDED_KEYCODE_FLAG + 0x30E0, 'ム'); // KATAKANA LETTER MU
885        map.put(EXTENDED_KEYCODE_FLAG + 0x30E1, 'メ'); // KATAKANA LETTER ME
886        map.put(EXTENDED_KEYCODE_FLAG + 0x30E2, 'モ'); // KATAKANA LETTER MO
887        map.put(EXTENDED_KEYCODE_FLAG + 0x30E4, 'ヤ'); // KATAKANA LETTER YA
888        map.put(EXTENDED_KEYCODE_FLAG + 0x30E6, 'ユ'); // KATAKANA LETTER YU
889        map.put(EXTENDED_KEYCODE_FLAG + 0x30E8, 'ヨ'); // KATAKANA LETTER YO
890        map.put(EXTENDED_KEYCODE_FLAG + 0x30E9, 'ラ'); // KATAKANA LETTER RA
891        map.put(EXTENDED_KEYCODE_FLAG + 0x30EA, 'リ'); // KATAKANA LETTER RI
892        map.put(EXTENDED_KEYCODE_FLAG + 0x30EB, 'ル'); // KATAKANA LETTER RU
893        map.put(EXTENDED_KEYCODE_FLAG + 0x30EC, 'レ'); // KATAKANA LETTER RE
894        map.put(EXTENDED_KEYCODE_FLAG + 0x30ED, 'ロ'); // KATAKANA LETTER RO
895        map.put(EXTENDED_KEYCODE_FLAG + 0x30EF, 'ワ'); // KATAKANA LETTER WA
896        map.put(EXTENDED_KEYCODE_FLAG + 0x30F3, 'ン'); // KATAKANA LETTER N
897        map.put(EXTENDED_KEYCODE_FLAG + 0x30FC, 'ー'); // KATAKANA-HIRAGANA PROLONGED SOUND MARK
898    }
899}