910e62b5创建于 1月15日历史提交
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.


#include "ui/events/keycodes/keysym_to_unicode.h"

#include <stddef.h>

#include <array>
#include <unordered_map>

#include "base/no_destructor.h"
#include "ui/gfx/x/keysyms/keysyms.h"

namespace ui {

struct KeysymToUnicode {
  uint32_t keysym;
  uint16_t unicode;
};
constexpr auto g_keysym_to_unicode_table = std::to_array<KeysymToUnicode>({
    // Control characters
    {XK_BackSpace, 0x0008},
    {XK_Tab, 0x0009},
    {XK_Linefeed, 0x000a},
    {XK_Clear, 0x000b},
    {XK_Return, 0x000d},
    {XK_Escape, 0x001b},
    {XK_Delete, 0x007f},

    // Numeric keypad
    {XK_KP_Space, 0x0020},
    {XK_KP_Tab, 0x0009},
    {XK_KP_Enter, 0x000d},
    {XK_KP_Equal, 0x003d},
    {XK_KP_Multiply, 0x002a},
    {XK_KP_Add, 0x002b},
    {XK_KP_Separator, 0x002c},
    {XK_KP_Subtract, 0x002d},
    {XK_KP_Decimal, 0x002e},
    {XK_KP_Divide, 0x002f},
    {XK_KP_0, 0x0030},
    {XK_KP_1, 0x0031},
    {XK_KP_2, 0x0032},
    {XK_KP_3, 0x0033},
    {XK_KP_4, 0x0034},
    {XK_KP_5, 0x0035},
    {XK_KP_6, 0x0036},
    {XK_KP_7, 0x0037},
    {XK_KP_8, 0x0038},
    {XK_KP_9, 0x0039},

    // Latin 1 KeySyms map 1:1 to Unicode

    // Latin 2
    {XK_Aogonek, 0x0104},       // LATIN CAPITAL LETTER A WITH OGONEK
    {XK_breve, 0x02D8},         // BREVE
    {XK_Lstroke, 0x0141},       // LATIN CAPITAL LETTER L WITH STROKE
    {XK_Lcaron, 0x013D},        // LATIN CAPITAL LETTER L WITH CARON
    {XK_Sacute, 0x015A},        // LATIN CAPITAL LETTER S WITH ACUTE
    {XK_Scaron, 0x0160},        // LATIN CAPITAL LETTER S WITH CARON
    {XK_Scedilla, 0x015E},      // LATIN CAPITAL LETTER S WITH CEDILLA
    {XK_Tcaron, 0x0164},        // LATIN CAPITAL LETTER T WITH CARON
    {XK_Zacute, 0x0179},        // LATIN CAPITAL LETTER Z WITH ACUTE
    {XK_Zcaron, 0x017D},        // LATIN CAPITAL LETTER Z WITH CARON
    {XK_Zabovedot, 0x017B},     // LATIN CAPITAL LETTER Z WITH DOT ABOVE
    {XK_aogonek, 0x0105},       // LATIN SMALL LETTER A WITH OGONEK
    {XK_ogonek, 0x02DB},        // OGONEK
    {XK_lstroke, 0x0142},       // LATIN SMALL LETTER L WITH STROKE
    {XK_lcaron, 0x013E},        // LATIN SMALL LETTER L WITH CARON
    {XK_sacute, 0x015B},        // LATIN SMALL LETTER S WITH ACUTE
    {XK_caron, 0x02C7},         // CARON
    {XK_scaron, 0x0161},        // LATIN SMALL LETTER S WITH CARON
    {XK_scedilla, 0x015F},      // LATIN SMALL LETTER S WITH CEDILLA
    {XK_tcaron, 0x0165},        // LATIN SMALL LETTER T WITH CARON
    {XK_zacute, 0x017A},        // LATIN SMALL LETTER Z WITH ACUTE
    {XK_doubleacute, 0x02DD},   // DOUBLE ACUTE ACCENT
    {XK_zcaron, 0x017E},        // LATIN SMALL LETTER Z WITH CARON
    {XK_zabovedot, 0x017C},     // LATIN SMALL LETTER Z WITH DOT ABOVE
    {XK_Racute, 0x0154},        // LATIN CAPITAL LETTER R WITH ACUTE
    {XK_Abreve, 0x0102},        // LATIN CAPITAL LETTER A WITH BREVE
    {XK_Lacute, 0x0139},        // LATIN CAPITAL LETTER L WITH ACUTE
    {XK_Cacute, 0x0106},        // LATIN CAPITAL LETTER C WITH ACUTE
    {XK_Ccaron, 0x010C},        // LATIN CAPITAL LETTER C WITH CARON
    {XK_Eogonek, 0x0118},       // LATIN CAPITAL LETTER E WITH OGONEK
    {XK_Ecaron, 0x011A},        // LATIN CAPITAL LETTER E WITH CARON
    {XK_Dcaron, 0x010E},        // LATIN CAPITAL LETTER D WITH CARON
    {XK_Dstroke, 0x0110},       // LATIN CAPITAL LETTER D WITH STROKE
    {XK_Nacute, 0x0143},        // LATIN CAPITAL LETTER N WITH ACUTE
    {XK_Ncaron, 0x0147},        // LATIN CAPITAL LETTER N WITH CARON
    {XK_Odoubleacute, 0x0150},  // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
    {XK_Rcaron, 0x0158},        // LATIN CAPITAL LETTER R WITH CARON
    {XK_Uring, 0x016E},         // LATIN CAPITAL LETTER U WITH RING ABOVE
    {XK_Udoubleacute, 0x0170},  // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
    {XK_Tcedilla, 0x0162},      // LATIN CAPITAL LETTER T WITH CEDILLA
    {XK_racute, 0x0155},        // LATIN SMALL LETTER R WITH ACUTE
    {XK_abreve, 0x0103},        // LATIN SMALL LETTER A WITH BREVE
    {XK_lacute, 0x013A},        // LATIN SMALL LETTER L WITH ACUTE
    {XK_cacute, 0x0107},        // LATIN SMALL LETTER C WITH ACUTE
    {XK_ccaron, 0x010D},        // LATIN SMALL LETTER C WITH CARON
    {XK_eogonek, 0x0119},       // LATIN SMALL LETTER E WITH OGONEK
    {XK_ecaron, 0x011B},        // LATIN SMALL LETTER E WITH CARON
    {XK_dcaron, 0x010F},        // LATIN SMALL LETTER D WITH CARON
    {XK_dstroke, 0x0111},       // LATIN SMALL LETTER D WITH STROKE
    {XK_nacute, 0x0144},        // LATIN SMALL LETTER N WITH ACUTE
    {XK_ncaron, 0x0148},        // LATIN SMALL LETTER N WITH CARON
    {XK_odoubleacute, 0x0151},  // LATIN SMALL LETTER O WITH DOUBLE ACUTE
    {XK_rcaron, 0x0159},        // LATIN SMALL LETTER R WITH CARON
    {XK_uring, 0x016F},         // LATIN SMALL LETTER U WITH RING ABOVE
    {XK_udoubleacute, 0x0171},  // LATIN SMALL LETTER U WITH DOUBLE ACUTE
    {XK_tcedilla, 0x0163},      // LATIN SMALL LETTER T WITH CEDILLA
    {XK_abovedot, 0x02D9},      // DOT ABOVE

    // Latin 3
    {XK_Hstroke, 0x0126},      // LATIN CAPITAL LETTER H WITH STROKE
    {XK_Hcircumflex, 0x0124},  // LATIN CAPITAL LETTER H WITH CIRCUMFLEX
    {XK_Iabovedot, 0x0130},    // LATIN CAPITAL LETTER I WITH DOT ABOVE
    {XK_Gbreve, 0x011E},       // LATIN CAPITAL LETTER G WITH BREVE
    {XK_Jcircumflex, 0x0134},  // LATIN CAPITAL LETTER J WITH CIRCUMFLEX
    {XK_hstroke, 0x0127},      // LATIN SMALL LETTER H WITH STROKE
    {XK_hcircumflex, 0x0125},  // LATIN SMALL LETTER H WITH CIRCUMFLEX
    {XK_idotless, 0x0131},     // LATIN SMALL LETTER DOTLESS I
    {XK_gbreve, 0x011F},       // LATIN SMALL LETTER G WITH BREVE
    {XK_jcircumflex, 0x0135},  // LATIN SMALL LETTER J WITH CIRCUMFLEX
    {XK_Cabovedot, 0x010A},    // LATIN CAPITAL LETTER C WITH DOT ABOVE
    {XK_Ccircumflex, 0x0108},  // LATIN CAPITAL LETTER C WITH CIRCUMFLEX
    {XK_Gabovedot, 0x0120},    // LATIN CAPITAL LETTER G WITH DOT ABOVE
    {XK_Gcircumflex, 0x011C},  // LATIN CAPITAL LETTER G WITH CIRCUMFLEX
    {XK_Ubreve, 0x016C},       // LATIN CAPITAL LETTER U WITH BREVE
    {XK_Scircumflex, 0x015C},  // LATIN CAPITAL LETTER S WITH CIRCUMFLEX
    {XK_cabovedot, 0x010B},    // LATIN SMALL LETTER C WITH DOT ABOVE
    {XK_ccircumflex, 0x0109},  // LATIN SMALL LETTER C WITH CIRCUMFLEX
    {XK_gabovedot, 0x0121},    // LATIN SMALL LETTER G WITH DOT ABOVE
    {XK_gcircumflex, 0x011D},  // LATIN SMALL LETTER G WITH CIRCUMFLEX
    {XK_ubreve, 0x016D},       // LATIN SMALL LETTER U WITH BREVE
    {XK_scircumflex, 0x015D},  // LATIN SMALL LETTER S WITH CIRCUMFLEX

    // Latin 4
    {XK_kra, 0x0138},        // LATIN SMALL LETTER KRA
    {XK_Rcedilla, 0x0156},   // LATIN CAPITAL LETTER R WITH CEDILLA
    {XK_Itilde, 0x0128},     // LATIN CAPITAL LETTER I WITH TILDE
    {XK_Lcedilla, 0x013B},   // LATIN CAPITAL LETTER L WITH CEDILLA
    {XK_Emacron, 0x0112},    // LATIN CAPITAL LETTER E WITH MACRON
    {XK_Gcedilla, 0x0122},   // LATIN CAPITAL LETTER G WITH CEDILLA
    {XK_Tslash, 0x0166},     // LATIN CAPITAL LETTER T WITH STROKE
    {XK_rcedilla, 0x0157},   // LATIN SMALL LETTER R WITH CEDILLA
    {XK_itilde, 0x0129},     // LATIN SMALL LETTER I WITH TILDE
    {XK_lcedilla, 0x013C},   // LATIN SMALL LETTER L WITH CEDILLA
    {XK_emacron, 0x0113},    // LATIN SMALL LETTER E WITH MACRON
    {XK_gcedilla, 0x0123},   // LATIN SMALL LETTER G WITH CEDILLA
    {XK_tslash, 0x0167},     // LATIN SMALL LETTER T WITH STROKE
    {XK_ENG, 0x014A},        // LATIN CAPITAL LETTER ENG
    {XK_eng, 0x014B},        // LATIN SMALL LETTER ENG
    {XK_Amacron, 0x0100},    // LATIN CAPITAL LETTER A WITH MACRON
    {XK_Iogonek, 0x012E},    // LATIN CAPITAL LETTER I WITH OGONEK
    {XK_Eabovedot, 0x0116},  // LATIN CAPITAL LETTER E WITH DOT ABOVE
    {XK_Imacron, 0x012A},    // LATIN CAPITAL LETTER I WITH MACRON
    {XK_Ncedilla, 0x0145},   // LATIN CAPITAL LETTER N WITH CEDILLA
    {XK_Omacron, 0x014C},    // LATIN CAPITAL LETTER O WITH MACRON
    {XK_Kcedilla, 0x0136},   // LATIN CAPITAL LETTER K WITH CEDILLA
    {XK_Uogonek, 0x0172},    // LATIN CAPITAL LETTER U WITH OGONEK
    {XK_Utilde, 0x0168},     // LATIN CAPITAL LETTER U WITH TILDE
    {XK_Umacron, 0x016A},    // LATIN CAPITAL LETTER U WITH MACRON
    {XK_amacron, 0x0101},    // LATIN SMALL LETTER A WITH MACRON
    {XK_iogonek, 0x012F},    // LATIN SMALL LETTER I WITH OGONEK
    {XK_eabovedot, 0x0117},  // LATIN SMALL LETTER E WITH DOT ABOVE
    {XK_imacron, 0x012B},    // LATIN SMALL LETTER I WITH MACRON
    {XK_ncedilla, 0x0146},   // LATIN SMALL LETTER N WITH CEDILLA
    {XK_omacron, 0x014D},    // LATIN SMALL LETTER O WITH MACRON
    {XK_kcedilla, 0x0137},   // LATIN SMALL LETTER K WITH CEDILLA
    {XK_uogonek, 0x0173},    // LATIN SMALL LETTER U WITH OGONEK
    {XK_utilde, 0x0169},     // LATIN SMALL LETTER U WITH TILDE
    {XK_umacron, 0x016B},    // LATIN SMALL LETTER U WITH MACRON

    // Latin 8 KeySyms map 1:1 to Unicode

    // Latin 9
    {XK_OE, 0x0152},          // LATIN CAPITAL LIGATURE OE
    {XK_oe, 0x0153},          // LATIN SMALL LIGATURE OE
    {XK_Ydiaeresis, 0x0178},  // LATIN CAPITAL LETTER Y WITH DIAERESIS

    // Katakana
    {XK_overline, 0x203E},             // OVERLINE
    {XK_kana_fullstop, 0x3002},        // IDEOGRAPHIC FULL STOP
    {XK_kana_openingbracket, 0x300C},  // LEFT CORNER BRACKET
    {XK_kana_closingbracket, 0x300D},  // RIGHT CORNER BRACKET
    {XK_kana_comma, 0x3001},           // IDEOGRAPHIC COMMA
    {XK_kana_conjunctive, 0x30FB},     // KATAKANA MIDDLE DOT
    {XK_kana_WO, 0x30F2},              // KATAKANA LETTER WO
    {XK_kana_a, 0x30A1},               // KATAKANA LETTER SMALL A
    {XK_kana_i, 0x30A3},               // KATAKANA LETTER SMALL I
    {XK_kana_u, 0x30A5},               // KATAKANA LETTER SMALL U
    {XK_kana_e, 0x30A7},               // KATAKANA LETTER SMALL E
    {XK_kana_o, 0x30A9},               // KATAKANA LETTER SMALL O
    {XK_kana_ya, 0x30E3},              // KATAKANA LETTER SMALL YA
    {XK_kana_yu, 0x30E5},              // KATAKANA LETTER SMALL YU
    {XK_kana_yo, 0x30E7},              // KATAKANA LETTER SMALL YO
    {XK_kana_tsu, 0x30C3},             // KATAKANA LETTER SMALL TU
    {XK_prolongedsound, 0x30FC},       // KATAKANA-HIRAGANA PROLONGED SOUND MARK
    {XK_kana_A, 0x30A2},               // KATAKANA LETTER A
    {XK_kana_I, 0x30A4},               // KATAKANA LETTER I
    {XK_kana_U, 0x30A6},               // KATAKANA LETTER U
    {XK_kana_E, 0x30A8},               // KATAKANA LETTER E
    {XK_kana_O, 0x30AA},               // KATAKANA LETTER O
    {XK_kana_KA, 0x30AB},              // KATAKANA LETTER KA
    {XK_kana_KI, 0x30AD},              // KATAKANA LETTER KI
    {XK_kana_KU, 0x30AF},              // KATAKANA LETTER KU
    {XK_kana_KE, 0x30B1},              // KATAKANA LETTER KE
    {XK_kana_KO, 0x30B3},              // KATAKANA LETTER KO
    {XK_kana_SA, 0x30B5},              // KATAKANA LETTER SA
    {XK_kana_SHI, 0x30B7},             // KATAKANA LETTER SI
    {XK_kana_SU, 0x30B9},              // KATAKANA LETTER SU
    {XK_kana_SE, 0x30BB},              // KATAKANA LETTER SE
    {XK_kana_SO, 0x30BD},              // KATAKANA LETTER SO
    {XK_kana_TA, 0x30BF},              // KATAKANA LETTER TA
    {XK_kana_CHI, 0x30C1},             // KATAKANA LETTER TI
    {XK_kana_TSU, 0x30C4},             // KATAKANA LETTER TU
    {XK_kana_TE, 0x30C6},              // KATAKANA LETTER TE
    {XK_kana_TO, 0x30C8},              // KATAKANA LETTER TO
    {XK_kana_NA, 0x30CA},              // KATAKANA LETTER NA
    {XK_kana_NI, 0x30CB},              // KATAKANA LETTER NI
    {XK_kana_NU, 0x30CC},              // KATAKANA LETTER NU
    {XK_kana_NE, 0x30CD},              // KATAKANA LETTER NE
    {XK_kana_NO, 0x30CE},              // KATAKANA LETTER NO
    {XK_kana_HA, 0x30CF},              // KATAKANA LETTER HA
    {XK_kana_HI, 0x30D2},              // KATAKANA LETTER HI
    {XK_kana_FU, 0x30D5},              // KATAKANA LETTER HU
    {XK_kana_HE, 0x30D8},              // KATAKANA LETTER HE
    {XK_kana_HO, 0x30DB},              // KATAKANA LETTER HO
    {XK_kana_MA, 0x30DE},              // KATAKANA LETTER MA
    {XK_kana_MI, 0x30DF},              // KATAKANA LETTER MI
    {XK_kana_MU, 0x30E0},              // KATAKANA LETTER MU
    {XK_kana_ME, 0x30E1},              // KATAKANA LETTER ME
    {XK_kana_MO, 0x30E2},              // KATAKANA LETTER MO
    {XK_kana_YA, 0x30E4},              // KATAKANA LETTER YA
    {XK_kana_YU, 0x30E6},              // KATAKANA LETTER YU
    {XK_kana_YO, 0x30E8},              // KATAKANA LETTER YO
    {XK_kana_RA, 0x30E9},              // KATAKANA LETTER RA
    {XK_kana_RI, 0x30EA},              // KATAKANA LETTER RI
    {XK_kana_RU, 0x30EB},              // KATAKANA LETTER RU
    {XK_kana_RE, 0x30EC},              // KATAKANA LETTER RE
    {XK_kana_RO, 0x30ED},              // KATAKANA LETTER RO
    {XK_kana_WA, 0x30EF},              // KATAKANA LETTER WA
    {XK_kana_N, 0x30F3},               // KATAKANA LETTER N
    {XK_voicedsound, 0x309B},          // KATAKANA-HIRAGANA VOICED SOUND MARK
    {XK_semivoicedsound, 0x309C},  // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK

    // Arabic KeySyms partially map 1:1 to Unicode
    {XK_Arabic_comma, 0x060C},           // ARABIC COMMA
    {XK_Arabic_semicolon, 0x061B},       // ARABIC SEMICOLON
    {XK_Arabic_question_mark, 0x061F},   // ARABIC QUESTION MARK
    {XK_Arabic_hamza, 0x0621},           // ARABIC LETTER HAMZA
    {XK_Arabic_maddaonalef, 0x0622},     // ARABIC LETTER ALEF WITH MADDA ABOVE
    {XK_Arabic_hamzaonalef, 0x0623},     // ARABIC LETTER ALEF WITH HAMZA ABOVE
    {XK_Arabic_hamzaonwaw, 0x0624},      // ARABIC LETTER WAW WITH HAMZA ABOVE
    {XK_Arabic_hamzaunderalef, 0x0625},  // ARABIC LETTER ALEF WITH HAMZA BELOW
    {XK_Arabic_hamzaonyeh, 0x0626},      // ARABIC LETTER YEH WITH HAMZA ABOVE
    {XK_Arabic_alef, 0x0627},            // ARABIC LETTER ALEF
    {XK_Arabic_beh, 0x0628},             // ARABIC LETTER BEH
    {XK_Arabic_tehmarbuta, 0x0629},      // ARABIC LETTER TEH MARBUTA
    {XK_Arabic_teh, 0x062A},             // ARABIC LETTER TEH
    {XK_Arabic_theh, 0x062B},            // ARABIC LETTER THEH
    {XK_Arabic_jeem, 0x062C},            // ARABIC LETTER JEEM
    {XK_Arabic_hah, 0x062D},             // ARABIC LETTER HAH
    {XK_Arabic_khah, 0x062E},            // ARABIC LETTER KHAH
    {XK_Arabic_dal, 0x062F},             // ARABIC LETTER DAL
    {XK_Arabic_thal, 0x0630},            // ARABIC LETTER THAL
    {XK_Arabic_ra, 0x0631},              // ARABIC LETTER REH
    {XK_Arabic_zain, 0x0632},            // ARABIC LETTER ZAIN
    {XK_Arabic_seen, 0x0633},            // ARABIC LETTER SEEN
    {XK_Arabic_sheen, 0x0634},           // ARABIC LETTER SHEEN
    {XK_Arabic_sad, 0x0635},             // ARABIC LETTER SAD
    {XK_Arabic_dad, 0x0636},             // ARABIC LETTER DAD
    {XK_Arabic_tah, 0x0637},             // ARABIC LETTER TAH
    {XK_Arabic_zah, 0x0638},             // ARABIC LETTER ZAH
    {XK_Arabic_ain, 0x0639},             // ARABIC LETTER AIN
    {XK_Arabic_ghain, 0x063A},           // ARABIC LETTER GHAIN
    {XK_Arabic_tatweel, 0x0640},         // ARABIC TATWEEL
    {XK_Arabic_feh, 0x0641},             // ARABIC LETTER FEH
    {XK_Arabic_qaf, 0x0642},             // ARABIC LETTER QAF
    {XK_Arabic_kaf, 0x0643},             // ARABIC LETTER KAF
    {XK_Arabic_lam, 0x0644},             // ARABIC LETTER LAM
    {XK_Arabic_meem, 0x0645},            // ARABIC LETTER MEEM
    {XK_Arabic_noon, 0x0646},            // ARABIC LETTER NOON
    {XK_Arabic_ha, 0x0647},              // ARABIC LETTER HEH
    {XK_Arabic_waw, 0x0648},             // ARABIC LETTER WAW
    {XK_Arabic_alefmaksura, 0x0649},     // ARABIC LETTER ALEF MAKSURA
    {XK_Arabic_yeh, 0x064A},             // ARABIC LETTER YEH
    {XK_Arabic_fathatan, 0x064B},        // ARABIC FATHATAN
    {XK_Arabic_dammatan, 0x064C},        // ARABIC DAMMATAN
    {XK_Arabic_kasratan, 0x064D},        // ARABIC KASRATAN
    {XK_Arabic_fatha, 0x064E},           // ARABIC FATHA
    {XK_Arabic_damma, 0x064F},           // ARABIC DAMMA
    {XK_Arabic_kasra, 0x0650},           // ARABIC KASRA
    {XK_Arabic_shadda, 0x0651},          // ARABIC SHADDA
    {XK_Arabic_sukun, 0x0652},           // ARABIC SUKUN

    // Cyrillic KeySyms partially map 1:1 to Unicode
    {XK_Serbian_dje, 0x0452},    // CYRILLIC SMALL LETTER DJE
    {XK_Macedonia_gje, 0x0453},  // CYRILLIC SMALL LETTER GJE
    {XK_Cyrillic_io, 0x0451},    // CYRILLIC SMALL LETTER IO
    {XK_Ukrainian_ie, 0x0454},   // CYRILLIC SMALL LETTER UKRAINIAN IE
    {XK_Macedonia_dse, 0x0455},  // CYRILLIC SMALL LETTER DZE
    {XK_Ukrainian_i, 0x0456},  // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
    {XK_Ukrainian_yi, 0x0457},   // CYRILLIC SMALL LETTER YI
    {XK_Cyrillic_je, 0x0458},    // CYRILLIC SMALL LETTER JE
    {XK_Cyrillic_lje, 0x0459},   // CYRILLIC SMALL LETTER LJE
    {XK_Cyrillic_nje, 0x045A},   // CYRILLIC SMALL LETTER NJE
    {XK_Serbian_tshe, 0x045B},   // CYRILLIC SMALL LETTER TSHE
    {XK_Macedonia_kje, 0x045C},  // CYRILLIC SMALL LETTER KJE
    {XK_Ukrainian_ghe_with_upturn,
     0x0491},                          // CYRILLIC SMALL LETTER GHE WITH UPTURN
    {XK_Byelorussian_shortu, 0x045E},  // CYRILLIC SMALL LETTER SHORT U
    {XK_Cyrillic_dzhe, 0x045F},        // CYRILLIC SMALL LETTER DZHE
    {XK_numerosign, 0x2116},           // NUMERO SIGN
    {XK_Serbian_DJE, 0x0402},          // CYRILLIC CAPITAL LETTER DJE
    {XK_Macedonia_GJE, 0x0403},        // CYRILLIC CAPITAL LETTER GJE
    {XK_Cyrillic_IO, 0x0401},          // CYRILLIC CAPITAL LETTER IO
    {XK_Ukrainian_IE, 0x0404},         // CYRILLIC CAPITAL LETTER UKRAINIAN IE
    {XK_Macedonia_DSE, 0x0405},        // CYRILLIC CAPITAL LETTER DZE
    {XK_Ukrainian_I,
     0x0406},  // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
    {XK_Ukrainian_YI, 0x0407},   // CYRILLIC CAPITAL LETTER YI
    {XK_Cyrillic_JE, 0x0408},    // CYRILLIC CAPITAL LETTER JE
    {XK_Cyrillic_LJE, 0x0409},   // CYRILLIC CAPITAL LETTER LJE
    {XK_Cyrillic_NJE, 0x040A},   // CYRILLIC CAPITAL LETTER NJE
    {XK_Serbian_TSHE, 0x040B},   // CYRILLIC CAPITAL LETTER TSHE
    {XK_Macedonia_KJE, 0x040C},  // CYRILLIC CAPITAL LETTER KJE
    {XK_Ukrainian_GHE_WITH_UPTURN,
     0x0490},  // CYRILLIC CAPITAL LETTER GHE WITH UPTURN
    {XK_Byelorussian_SHORTU, 0x040E},  // CYRILLIC CAPITAL LETTER SHORT U
    {XK_Cyrillic_DZHE, 0x040F},        // CYRILLIC CAPITAL LETTER DZHE
    {XK_Cyrillic_yu, 0x044E},          // CYRILLIC SMALL LETTER YU
    {XK_Cyrillic_a, 0x0430},           // CYRILLIC SMALL LETTER A
    {XK_Cyrillic_be, 0x0431},          // CYRILLIC SMALL LETTER BE
    {XK_Cyrillic_tse, 0x0446},         // CYRILLIC SMALL LETTER TSE
    {XK_Cyrillic_de, 0x0434},          // CYRILLIC SMALL LETTER DE
    {XK_Cyrillic_ie, 0x0435},          // CYRILLIC SMALL LETTER IE
    {XK_Cyrillic_ef, 0x0444},          // CYRILLIC SMALL LETTER EF
    {XK_Cyrillic_ghe, 0x0433},         // CYRILLIC SMALL LETTER GHE
    {XK_Cyrillic_ha, 0x0445},          // CYRILLIC SMALL LETTER HA
    {XK_Cyrillic_i, 0x0438},           // CYRILLIC SMALL LETTER I
    {XK_Cyrillic_shorti, 0x0439},      // CYRILLIC SMALL LETTER SHORT I
    {XK_Cyrillic_ka, 0x043A},          // CYRILLIC SMALL LETTER KA
    {XK_Cyrillic_el, 0x043B},          // CYRILLIC SMALL LETTER EL
    {XK_Cyrillic_em, 0x043C},          // CYRILLIC SMALL LETTER EM
    {XK_Cyrillic_en, 0x043D},          // CYRILLIC SMALL LETTER EN
    {XK_Cyrillic_o, 0x043E},           // CYRILLIC SMALL LETTER O
    {XK_Cyrillic_pe, 0x043F},          // CYRILLIC SMALL LETTER PE
    {XK_Cyrillic_ya, 0x044F},          // CYRILLIC SMALL LETTER YA
    {XK_Cyrillic_er, 0x0440},          // CYRILLIC SMALL LETTER ER
    {XK_Cyrillic_es, 0x0441},          // CYRILLIC SMALL LETTER ES
    {XK_Cyrillic_te, 0x0442},          // CYRILLIC SMALL LETTER TE
    {XK_Cyrillic_u, 0x0443},           // CYRILLIC SMALL LETTER U
    {XK_Cyrillic_zhe, 0x0436},         // CYRILLIC SMALL LETTER ZHE
    {XK_Cyrillic_ve, 0x0432},          // CYRILLIC SMALL LETTER VE
    {XK_Cyrillic_softsign, 0x044C},    // CYRILLIC SMALL LETTER SOFT SIGN
    {XK_Cyrillic_yeru, 0x044B},        // CYRILLIC SMALL LETTER YERU
    {XK_Cyrillic_ze, 0x0437},          // CYRILLIC SMALL LETTER ZE
    {XK_Cyrillic_sha, 0x0448},         // CYRILLIC SMALL LETTER SHA
    {XK_Cyrillic_e, 0x044D},           // CYRILLIC SMALL LETTER E
    {XK_Cyrillic_shcha, 0x0449},       // CYRILLIC SMALL LETTER SHCHA
    {XK_Cyrillic_che, 0x0447},         // CYRILLIC SMALL LETTER CHE
    {XK_Cyrillic_hardsign, 0x044A},    // CYRILLIC SMALL LETTER HARD SIGN
    {XK_Cyrillic_YU, 0x042E},          // CYRILLIC CAPITAL LETTER YU
    {XK_Cyrillic_A, 0x0410},           // CYRILLIC CAPITAL LETTER A
    {XK_Cyrillic_BE, 0x0411},          // CYRILLIC CAPITAL LETTER BE
    {XK_Cyrillic_TSE, 0x0426},         // CYRILLIC CAPITAL LETTER TSE
    {XK_Cyrillic_DE, 0x0414},          // CYRILLIC CAPITAL LETTER DE
    {XK_Cyrillic_IE, 0x0415},          // CYRILLIC CAPITAL LETTER IE
    {XK_Cyrillic_EF, 0x0424},          // CYRILLIC CAPITAL LETTER EF
    {XK_Cyrillic_GHE, 0x0413},         // CYRILLIC CAPITAL LETTER GHE
    {XK_Cyrillic_HA, 0x0425},          // CYRILLIC CAPITAL LETTER HA
    {XK_Cyrillic_I, 0x0418},           // CYRILLIC CAPITAL LETTER I
    {XK_Cyrillic_SHORTI, 0x0419},      // CYRILLIC CAPITAL LETTER SHORT I
    {XK_Cyrillic_KA, 0x041A},          // CYRILLIC CAPITAL LETTER KA
    {XK_Cyrillic_EL, 0x041B},          // CYRILLIC CAPITAL LETTER EL
    {XK_Cyrillic_EM, 0x041C},          // CYRILLIC CAPITAL LETTER EM
    {XK_Cyrillic_EN, 0x041D},          // CYRILLIC CAPITAL LETTER EN
    {XK_Cyrillic_O, 0x041E},           // CYRILLIC CAPITAL LETTER O
    {XK_Cyrillic_PE, 0x041F},          // CYRILLIC CAPITAL LETTER PE
    {XK_Cyrillic_YA, 0x042F},          // CYRILLIC CAPITAL LETTER YA
    {XK_Cyrillic_ER, 0x0420},          // CYRILLIC CAPITAL LETTER ER
    {XK_Cyrillic_ES, 0x0421},          // CYRILLIC CAPITAL LETTER ES
    {XK_Cyrillic_TE, 0x0422},          // CYRILLIC CAPITAL LETTER TE
    {XK_Cyrillic_U, 0x0423},           // CYRILLIC CAPITAL LETTER U
    {XK_Cyrillic_ZHE, 0x0416},         // CYRILLIC CAPITAL LETTER ZHE
    {XK_Cyrillic_VE, 0x0412},          // CYRILLIC CAPITAL LETTER VE
    {XK_Cyrillic_SOFTSIGN, 0x042C},    // CYRILLIC CAPITAL LETTER SOFT SIGN
    {XK_Cyrillic_YERU, 0x042B},        // CYRILLIC CAPITAL LETTER YERU
    {XK_Cyrillic_ZE, 0x0417},          // CYRILLIC CAPITAL LETTER ZE
    {XK_Cyrillic_SHA, 0x0428},         // CYRILLIC CAPITAL LETTER SHA
    {XK_Cyrillic_E, 0x042D},           // CYRILLIC CAPITAL LETTER E
    {XK_Cyrillic_SHCHA, 0x0429},       // CYRILLIC CAPITAL LETTER SHCHA
    {XK_Cyrillic_CHE, 0x0427},         // CYRILLIC CAPITAL LETTER CHE
    {XK_Cyrillic_HARDSIGN, 0x042A},    // CYRILLIC CAPITAL LETTER HARD SIGN

    // Greek
    {XK_Greek_ALPHAaccent, 0x0386},  // GREEK CAPITAL LETTER ALPHA WITH TONOS
    {XK_Greek_EPSILONaccent,
     0x0388},                       // GREEK CAPITAL LETTER EPSILON WITH TONOS
    {XK_Greek_ETAaccent, 0x0389},   // GREEK CAPITAL LETTER ETA WITH TONOS
    {XK_Greek_IOTAaccent, 0x038A},  // GREEK CAPITAL LETTER IOTA WITH TONOS
    {XK_Greek_IOTAdieresis,
     0x03AA},  // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
    {XK_Greek_OMICRONaccent,
     0x038C},  // GREEK CAPITAL LETTER OMICRON WITH TONOS
    {XK_Greek_UPSILONaccent,
     0x038E},  // GREEK CAPITAL LETTER UPSILON WITH TONOS
    {XK_Greek_UPSILONdieresis,
     0x03AB},  // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
    {XK_Greek_OMEGAaccent, 0x038F},     // GREEK CAPITAL LETTER OMEGA WITH TONOS
    {XK_Greek_accentdieresis, 0x0385},  // GREEK DIALYTIKA TONOS
    {XK_Greek_horizbar, 0x2015},        // HORIZONTAL BAR
    {XK_Greek_alphaaccent, 0x03AC},     // GREEK SMALL LETTER ALPHA WITH TONOS
    {XK_Greek_epsilonaccent, 0x03AD},   // GREEK SMALL LETTER EPSILON WITH TONOS
    {XK_Greek_etaaccent, 0x03AE},       // GREEK SMALL LETTER ETA WITH TONOS
    {XK_Greek_iotaaccent, 0x03AF},      // GREEK SMALL LETTER IOTA WITH TONOS
    {XK_Greek_iotadieresis, 0x03CA},  // GREEK SMALL LETTER IOTA WITH DIALYTIKA
    {XK_Greek_iotaaccentdieresis,
     0x0390},  // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
    {XK_Greek_omicronaccent, 0x03CC},  // GREEK SMALL LETTER OMICRON WITH TONOS
    {XK_Greek_upsilonaccent, 0x03CD},  // GREEK SMALL LETTER UPSILON WITH TONOS
    {XK_Greek_upsilondieresis,
     0x03CB},  // GREEK SMALL LETTER UPSILON WITH DIALYTIKA
    {XK_Greek_upsilonaccentdieresis,
     0x03B0},  // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
    {XK_Greek_omegaaccent, 0x03CE},      // GREEK SMALL LETTER OMEGA WITH TONOS
    {XK_Greek_ALPHA, 0x0391},            // GREEK CAPITAL LETTER ALPHA
    {XK_Greek_BETA, 0x0392},             // GREEK CAPITAL LETTER BETA
    {XK_Greek_GAMMA, 0x0393},            // GREEK CAPITAL LETTER GAMMA
    {XK_Greek_DELTA, 0x0394},            // GREEK CAPITAL LETTER DELTA
    {XK_Greek_EPSILON, 0x0395},          // GREEK CAPITAL LETTER EPSILON
    {XK_Greek_ZETA, 0x0396},             // GREEK CAPITAL LETTER ZETA
    {XK_Greek_ETA, 0x0397},              // GREEK CAPITAL LETTER ETA
    {XK_Greek_THETA, 0x0398},            // GREEK CAPITAL LETTER THETA
    {XK_Greek_IOTA, 0x0399},             // GREEK CAPITAL LETTER IOTA
    {XK_Greek_KAPPA, 0x039A},            // GREEK CAPITAL LETTER KAPPA
    {XK_Greek_LAMDA, 0x039B},            // GREEK CAPITAL LETTER LAMDA
    {XK_Greek_LAMBDA, 0x039B},           // GREEK CAPITAL LETTER LAMDA
    {XK_Greek_MU, 0x039C},               // GREEK CAPITAL LETTER MU
    {XK_Greek_NU, 0x039D},               // GREEK CAPITAL LETTER NU
    {XK_Greek_XI, 0x039E},               // GREEK CAPITAL LETTER XI
    {XK_Greek_OMICRON, 0x039F},          // GREEK CAPITAL LETTER OMICRON
    {XK_Greek_PI, 0x03A0},               // GREEK CAPITAL LETTER PI
    {XK_Greek_RHO, 0x03A1},              // GREEK CAPITAL LETTER RHO
    {XK_Greek_SIGMA, 0x03A3},            // GREEK CAPITAL LETTER SIGMA
    {XK_Greek_TAU, 0x03A4},              // GREEK CAPITAL LETTER TAU
    {XK_Greek_UPSILON, 0x03A5},          // GREEK CAPITAL LETTER UPSILON
    {XK_Greek_PHI, 0x03A6},              // GREEK CAPITAL LETTER PHI
    {XK_Greek_CHI, 0x03A7},              // GREEK CAPITAL LETTER CHI
    {XK_Greek_PSI, 0x03A8},              // GREEK CAPITAL LETTER PSI
    {XK_Greek_OMEGA, 0x03A9},            // GREEK CAPITAL LETTER OMEGA
    {XK_Greek_alpha, 0x03B1},            // GREEK SMALL LETTER ALPHA
    {XK_Greek_beta, 0x03B2},             // GREEK SMALL LETTER BETA
    {XK_Greek_gamma, 0x03B3},            // GREEK SMALL LETTER GAMMA
    {XK_Greek_delta, 0x03B4},            // GREEK SMALL LETTER DELTA
    {XK_Greek_epsilon, 0x03B5},          // GREEK SMALL LETTER EPSILON
    {XK_Greek_zeta, 0x03B6},             // GREEK SMALL LETTER ZETA
    {XK_Greek_eta, 0x03B7},              // GREEK SMALL LETTER ETA
    {XK_Greek_theta, 0x03B8},            // GREEK SMALL LETTER THETA
    {XK_Greek_iota, 0x03B9},             // GREEK SMALL LETTER IOTA
    {XK_Greek_kappa, 0x03BA},            // GREEK SMALL LETTER KAPPA
    {XK_Greek_lamda, 0x03BB},            // GREEK SMALL LETTER LAMDA
    {XK_Greek_lambda, 0x03BB},           // GREEK SMALL LETTER LAMDA
    {XK_Greek_mu, 0x03BC},               // GREEK SMALL LETTER MU
    {XK_Greek_nu, 0x03BD},               // GREEK SMALL LETTER NU
    {XK_Greek_xi, 0x03BE},               // GREEK SMALL LETTER XI
    {XK_Greek_omicron, 0x03BF},          // GREEK SMALL LETTER OMICRON
    {XK_Greek_pi, 0x03C0},               // GREEK SMALL LETTER PI
    {XK_Greek_rho, 0x03C1},              // GREEK SMALL LETTER RHO
    {XK_Greek_sigma, 0x03C3},            // GREEK SMALL LETTER SIGMA
    {XK_Greek_finalsmallsigma, 0x03C2},  // GREEK SMALL LETTER FINAL SIGMA
    {XK_Greek_tau, 0x03C4},              // GREEK SMALL LETTER TAU
    {XK_Greek_upsilon, 0x03C5},          // GREEK SMALL LETTER UPSILON
    {XK_Greek_phi, 0x03C6},              // GREEK SMALL LETTER PHI
    {XK_Greek_chi, 0x03C7},              // GREEK SMALL LETTER CHI
    {XK_Greek_psi, 0x03C8},              // GREEK SMALL LETTER PSI
    {XK_Greek_omega, 0x03C9},            // GREEK SMALL LETTER OMEGA

    // Technical
    {XK_leftradical, 0x23B7},            // RADICAL SYMBOL BOTTOM
    {XK_topleftradical, 0x250C},         // BOX DRAWINGS LIGHT DOWN AND RIGHT
    {XK_horizconnector, 0x2500},         // BOX DRAWINGS LIGHT HORIZONTAL
    {XK_topintegral, 0x2320},            // TOP HALF INTEGRAL
    {XK_botintegral, 0x2321},            // BOTTOM HALF INTEGRAL
    {XK_vertconnector, 0x2502},          // BOX DRAWINGS LIGHT VERTICAL
    {XK_topleftsqbracket, 0x23A1},       // LEFT SQUARE BRACKET UPPER CORNER
    {XK_botleftsqbracket, 0x23A3},       // LEFT SQUARE BRACKET LOWER CORNER
    {XK_toprightsqbracket, 0x23A4},      // RIGHT SQUARE BRACKET UPPER CORNER
    {XK_botrightsqbracket, 0x23A6},      // RIGHT SQUARE BRACKET LOWER CORNER
    {XK_topleftparens, 0x239B},          // LEFT PARENTHESIS UPPER HOOK
    {XK_botleftparens, 0x239D},          // LEFT PARENTHESIS LOWER HOOK
    {XK_toprightparens, 0x239E},         // RIGHT PARENTHESIS UPPER HOOK
    {XK_botrightparens, 0x23A0},         // RIGHT PARENTHESIS LOWER HOOK
    {XK_leftmiddlecurlybrace, 0x23A8},   // LEFT CURLY BRACKET MIDDLE PIECE
    {XK_rightmiddlecurlybrace, 0x23AC},  // RIGHT CURLY BRACKET MIDDLE PIECE
    {XK_lessthanequal, 0x2264},          // LESS-THAN OR EQUAL TO
    {XK_notequal, 0x2260},               // NOT EQUAL TO
    {XK_greaterthanequal, 0x2265},       // GREATER-THAN OR EQUAL TO
    {XK_integral, 0x222B},               // INTEGRAL
    {XK_therefore, 0x2234},              // THEREFORE
    {XK_variation, 0x221D},              // PROPORTIONAL TO
    {XK_infinity, 0x221E},               // INFINITY
    {XK_nabla, 0x2207},                  // NABLA
    {XK_approximate, 0x223C},            // TILDE OPERATOR
    {XK_similarequal, 0x2243},           // ASYMPTOTICALLY EQUAL TO
    {XK_ifonlyif, 0x21D4},               // LEFT RIGHT DOUBLE ARROW
    {XK_implies, 0x21D2},                // RIGHTWARDS DOUBLE ARROW
    {XK_identical, 0x2261},              // IDENTICAL TO
    {XK_radical, 0x221A},                // SQUARE ROOT
    {XK_includedin, 0x2282},             // SUBSET OF
    {XK_includes, 0x2283},               // SUPERSET OF
    {XK_intersection, 0x2229},           // INTERSECTION
    {XK_union, 0x222A},                  // UNION
    {XK_logicaland, 0x2227},             // LOGICAL AND
    {XK_logicalor, 0x2228},              // LOGICAL OR
    {XK_partialderivative, 0x2202},      // PARTIAL DIFFERENTIAL
    {XK_function, 0x0192},               // LATIN SMALL LETTER F WITH HOOK
    {XK_leftarrow, 0x2190},              // LEFTWARDS ARROW
    {XK_uparrow, 0x2191},                // UPWARDS ARROW
    {XK_rightarrow, 0x2192},             // RIGHTWARDS ARROW
    {XK_downarrow, 0x2193},              // DOWNWARDS ARROW

    // Special
    {XK_soliddiamond, 0x25C6},    // BLACK DIAMOND
    {XK_checkerboard, 0x2592},    // MEDIUM SHADE
    {XK_ht, 0x2409},              // SYMBOL FOR HORIZONTAL TABULATION
    {XK_ff, 0x240C},              // SYMBOL FOR FORM FEED
    {XK_cr, 0x240D},              // SYMBOL FOR CARRIAGE RETURN
    {XK_lf, 0x240A},              // SYMBOL FOR LINE FEED
    {XK_nl, 0x2424},              // SYMBOL FOR NEWLINE
    {XK_vt, 0x240B},              // SYMBOL FOR VERTICAL TABULATION
    {XK_lowrightcorner, 0x2518},  // BOX DRAWINGS LIGHT UP AND LEFT
    {XK_uprightcorner, 0x2510},   // BOX DRAWINGS LIGHT DOWN AND LEFT
    {XK_upleftcorner, 0x250C},    // BOX DRAWINGS LIGHT DOWN AND RIGHT
    {XK_lowleftcorner, 0x2514},   // BOX DRAWINGS LIGHT UP AND RIGHT
    {XK_crossinglines, 0x253C},   // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
    {XK_horizlinescan1, 0x23BA},  // HORIZONTAL SCAN LINE-1
    {XK_horizlinescan3, 0x23BB},  // HORIZONTAL SCAN LINE-3
    {XK_horizlinescan5, 0x2500},  // BOX DRAWINGS LIGHT HORIZONTAL
    {XK_horizlinescan7, 0x23BC},  // HORIZONTAL SCAN LINE-7
    {XK_horizlinescan9, 0x23BD},  // HORIZONTAL SCAN LINE-9
    {XK_leftt, 0x251C},           // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
    {XK_rightt, 0x2524},          // BOX DRAWINGS LIGHT VERTICAL AND LEFT
    {XK_bott, 0x2534},            // BOX DRAWINGS LIGHT UP AND HORIZONTAL
    {XK_topt, 0x252C},            // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
    {XK_vertbar, 0x2502},         // BOX DRAWINGS LIGHT VERTICAL

    // Publishing
    {XK_emspace, 0x2003},               // EM SPACE
    {XK_enspace, 0x2002},               // EN SPACE
    {XK_em3space, 0x2004},              // THREE-PER-EM SPACE
    {XK_em4space, 0x2005},              // FOUR-PER-EM SPACE
    {XK_digitspace, 0x2007},            // FIGURE SPACE
    {XK_punctspace, 0x2008},            // PUNCTUATION SPACE
    {XK_thinspace, 0x2009},             // THIN SPACE
    {XK_hairspace, 0x200A},             // HAIR SPACE
    {XK_emdash, 0x2014},                // EM DASH
    {XK_endash, 0x2013},                // EN DASH
    {XK_signifblank, 0x2423},           // OPEN BOX
    {XK_ellipsis, 0x2026},              // HORIZONTAL ELLIPSIS
    {XK_doubbaselinedot, 0x2025},       // TWO DOT LEADER
    {XK_onethird, 0x2153},              // VULGAR FRACTION ONE THIRD
    {XK_twothirds, 0x2154},             // VULGAR FRACTION TWO THIRDS
    {XK_onefifth, 0x2155},              // VULGAR FRACTION ONE FIFTH
    {XK_twofifths, 0x2156},             // VULGAR FRACTION TWO FIFTHS
    {XK_threefifths, 0x2157},           // VULGAR FRACTION THREE FIFTHS
    {XK_fourfifths, 0x2158},            // VULGAR FRACTION FOUR FIFTHS
    {XK_onesixth, 0x2159},              // VULGAR FRACTION ONE SIXTH
    {XK_fivesixths, 0x215A},            // VULGAR FRACTION FIVE SIXTHS
    {XK_careof, 0x2105},                // CARE OF
    {XK_figdash, 0x2012},               // FIGURE DASH
    {XK_leftanglebracket, 0x27E8},      // MATHEMATICAL LEFT ANGLE BRACKET
    {XK_decimalpoint, 0x002E},          // FULL STOP
    {XK_rightanglebracket, 0x27E9},     // MATHEMATICAL RIGHT ANGLE BRACKET
    {XK_oneeighth, 0x215B},             // VULGAR FRACTION ONE EIGHTH
    {XK_threeeighths, 0x215C},          // VULGAR FRACTION THREE EIGHTHS
    {XK_fiveeighths, 0x215D},           // VULGAR FRACTION FIVE EIGHTHS
    {XK_seveneighths, 0x215E},          // VULGAR FRACTION SEVEN EIGHTHS
    {XK_trademark, 0x2122},             // TRADE MARK SIGN
    {XK_signaturemark, 0x2613},         // SALTIRE
    {XK_leftopentriangle, 0x25C1},      // WHITE LEFT-POINTING TRIANGLE
    {XK_rightopentriangle, 0x25B7},     // WHITE RIGHT-POINTING TRIANGLE
    {XK_emopencircle, 0x25CB},          // WHITE CIRCLE
    {XK_emopenrectangle, 0x25AF},       // WHITE VERTICAL RECTANGLE
    {XK_leftsinglequotemark, 0x2018},   // LEFT SINGLE QUOTATION MARK
    {XK_rightsinglequotemark, 0x2019},  // RIGHT SINGLE QUOTATION MARK
    {XK_leftdoublequotemark, 0x201C},   // LEFT DOUBLE QUOTATION MARK
    {XK_rightdoublequotemark, 0x201D},  // RIGHT DOUBLE QUOTATION MARK
    {XK_prescription, 0x211E},          // PRESCRIPTION TAKE
    {XK_minutes, 0x2032},               // PRIME
    {XK_seconds, 0x2033},               // DOUBLE PRIME
    {XK_latincross, 0x271D},            // LATIN CROSS
    {XK_filledrectbullet, 0x25AC},      // BLACK RECTANGLE
    {XK_filledlefttribullet, 0x25C0},   // BLACK LEFT-POINTING TRIANGLE
    {XK_filledrighttribullet, 0x25B6},  // BLACK RIGHT-POINTING TRIANGLE
    {XK_emfilledcircle, 0x25CF},        // BLACK CIRCLE
    {XK_emfilledrect, 0x25AE},          // BLACK VERTICAL RECTANGLE
    {XK_enopencircbullet, 0x25E6},      // WHITE BULLET
    {XK_enopensquarebullet, 0x25AB},    // WHITE SMALL SQUARE
    {XK_openrectbullet, 0x25AD},        // WHITE RECTANGLE
    {XK_opentribulletup, 0x25B3},       // WHITE UP-POINTING TRIANGLE
    {XK_opentribulletdown, 0x25BD},     // WHITE DOWN-POINTING TRIANGLE
    {XK_openstar, 0x2606},              // WHITE STAR
    {XK_enfilledcircbullet, 0x2022},    // BULLET
    {XK_enfilledsqbullet, 0x25AA},      // BLACK SMALL SQUARE
    {XK_filledtribulletup, 0x25B2},     // BLACK UP-POINTING TRIANGLE
    {XK_filledtribulletdown, 0x25BC},   // BLACK DOWN-POINTING TRIANGLE
    {XK_leftpointer, 0x261C},           // WHITE LEFT POINTING INDEX
    {XK_rightpointer, 0x261E},          // WHITE RIGHT POINTING INDEX
    {XK_club, 0x2663},                  // BLACK CLUB SUIT
    {XK_diamond, 0x2666},               // BLACK DIAMOND SUIT
    {XK_heart, 0x2665},                 // BLACK HEART SUIT
    {XK_maltesecross, 0x2720},          // MALTESE CROSS
    {XK_dagger, 0x2020},                // DAGGER
    {XK_doubledagger, 0x2021},          // DOUBLE DAGGER
    {XK_checkmark, 0x2713},             // CHECK MARK
    {XK_ballotcross, 0x2717},           // BALLOT X
    {XK_musicalsharp, 0x266F},          // MUSIC SHARP SIGN
    {XK_musicalflat, 0x266D},           // MUSIC FLAT SIGN
    {XK_malesymbol, 0x2642},            // MALE SIGN
    {XK_femalesymbol, 0x2640},          // FEMALE SIGN
    {XK_telephone, 0x260E},             // BLACK TELEPHONE
    {XK_telephonerecorder, 0x2315},     // TELEPHONE RECORDER
    {XK_phonographcopyright, 0x2117},   // SOUND RECORDING COPYRIGHT
    {XK_caret, 0x2038},                 // CARET
    {XK_singlelowquotemark, 0x201A},    // SINGLE LOW-9 QUOTATION MARK
    {XK_doublelowquotemark, 0x201E},    // DOUBLE LOW-9 QUOTATION MARK

    // APL
    {XK_leftcaret, 0x003C},   // LESS-THAN SIGN
    {XK_rightcaret, 0x003E},  // GREATER-THAN SIGN
    {XK_downcaret, 0x2228},   // LOGICAL OR
    {XK_upcaret, 0x2227},     // LOGICAL AND
    {XK_overbar, 0x00AF},     // MACRON
    {XK_downtack, 0x22A4},    // DOWN TACK
    {XK_upshoe, 0x2229},      // INTERSECTION
    {XK_downstile, 0x230A},   // LEFT FLOOR
    {XK_underbar, 0x005F},    // LOW LINE
    {XK_jot, 0x2218},         // RING OPERATOR
    {XK_quad, 0x2395},        // APL FUNCTIONAL SYMBOL QUAD
    {XK_uptack, 0x22A5},      // UP TACK
    {XK_circle, 0x25CB},      // WHITE CIRCLE
    {XK_upstile, 0x2308},     // LEFT CEILING
    {XK_downshoe, 0x222A},    // UNION
    {XK_rightshoe, 0x2283},   // SUPERSET OF
    {XK_leftshoe, 0x2282},    // SUBSET OF
    {XK_lefttack, 0x22A3},    // LEFT TACK
    {XK_righttack, 0x22A2},   // RIGHT TACK

    // Hebrew
    {XK_hebrew_doublelowline, 0x2017},  // DOUBLE LOW LINE
    {XK_hebrew_aleph, 0x05D0},          // HEBREW LETTER ALEF
    {XK_hebrew_bet, 0x05D1},            // HEBREW LETTER BET
    {XK_hebrew_gimel, 0x05D2},          // HEBREW LETTER GIMEL
    {XK_hebrew_dalet, 0x05D3},          // HEBREW LETTER DALET
    {XK_hebrew_he, 0x05D4},             // HEBREW LETTER HE
    {XK_hebrew_waw, 0x05D5},            // HEBREW LETTER VAV
    {XK_hebrew_zain, 0x05D6},           // HEBREW LETTER ZAYIN
    {XK_hebrew_chet, 0x05D7},           // HEBREW LETTER HET
    {XK_hebrew_tet, 0x05D8},            // HEBREW LETTER TET
    {XK_hebrew_yod, 0x05D9},            // HEBREW LETTER YOD
    {XK_hebrew_finalkaph, 0x05DA},      // HEBREW LETTER FINAL KAF
    {XK_hebrew_kaph, 0x05DB},           // HEBREW LETTER KAF
    {XK_hebrew_lamed, 0x05DC},          // HEBREW LETTER LAMED
    {XK_hebrew_finalmem, 0x05DD},       // HEBREW LETTER FINAL MEM
    {XK_hebrew_mem, 0x05DE},            // HEBREW LETTER MEM
    {XK_hebrew_finalnun, 0x05DF},       // HEBREW LETTER FINAL NUN
    {XK_hebrew_nun, 0x05E0},            // HEBREW LETTER NUN
    {XK_hebrew_samech, 0x05E1},         // HEBREW LETTER SAMEKH
    {XK_hebrew_ayin, 0x05E2},           // HEBREW LETTER AYIN
    {XK_hebrew_finalpe, 0x05E3},        // HEBREW LETTER FINAL PE
    {XK_hebrew_pe, 0x05E4},             // HEBREW LETTER PE
    {XK_hebrew_finalzade, 0x05E5},      // HEBREW LETTER FINAL TSADI
    {XK_hebrew_zade, 0x05E6},           // HEBREW LETTER TSADI
    {XK_hebrew_qoph, 0x05E7},           // HEBREW LETTER QOF
    {XK_hebrew_resh, 0x05E8},           // HEBREW LETTER RESH
    {XK_hebrew_shin, 0x05E9},           // HEBREW LETTER SHIN
    {XK_hebrew_taw, 0x05EA},            // HEBREW LETTER TAV

    // Thai
    {XK_Thai_kokai, 0x0E01},           // THAI CHARACTER KO KAI
    {XK_Thai_khokhai, 0x0E02},         // THAI CHARACTER KHO KHAI
    {XK_Thai_khokhuat, 0x0E03},        // THAI CHARACTER KHO KHUAT
    {XK_Thai_khokhwai, 0x0E04},        // THAI CHARACTER KHO KHWAI
    {XK_Thai_khokhon, 0x0E05},         // THAI CHARACTER KHO KHON
    {XK_Thai_khorakhang, 0x0E06},      // THAI CHARACTER KHO RAKHANG
    {XK_Thai_ngongu, 0x0E07},          // THAI CHARACTER NGO NGU
    {XK_Thai_chochan, 0x0E08},         // THAI CHARACTER CHO CHAN
    {XK_Thai_choching, 0x0E09},        // THAI CHARACTER CHO CHING
    {XK_Thai_chochang, 0x0E0A},        // THAI CHARACTER CHO CHANG
    {XK_Thai_soso, 0x0E0B},            // THAI CHARACTER SO SO
    {XK_Thai_chochoe, 0x0E0C},         // THAI CHARACTER CHO CHOE
    {XK_Thai_yoying, 0x0E0D},          // THAI CHARACTER YO YING
    {XK_Thai_dochada, 0x0E0E},         // THAI CHARACTER DO CHADA
    {XK_Thai_topatak, 0x0E0F},         // THAI CHARACTER TO PATAK
    {XK_Thai_thothan, 0x0E10},         // THAI CHARACTER THO THAN
    {XK_Thai_thonangmontho, 0x0E11},   // THAI CHARACTER THO NANGMONTHO
    {XK_Thai_thophuthao, 0x0E12},      // THAI CHARACTER THO PHUTHAO
    {XK_Thai_nonen, 0x0E13},           // THAI CHARACTER NO NEN
    {XK_Thai_dodek, 0x0E14},           // THAI CHARACTER DO DEK
    {XK_Thai_totao, 0x0E15},           // THAI CHARACTER TO TAO
    {XK_Thai_thothung, 0x0E16},        // THAI CHARACTER THO THUNG
    {XK_Thai_thothahan, 0x0E17},       // THAI CHARACTER THO THAHAN
    {XK_Thai_thothong, 0x0E18},        // THAI CHARACTER THO THONG
    {XK_Thai_nonu, 0x0E19},            // THAI CHARACTER NO NU
    {XK_Thai_bobaimai, 0x0E1A},        // THAI CHARACTER BO BAIMAI
    {XK_Thai_popla, 0x0E1B},           // THAI CHARACTER PO PLA
    {XK_Thai_phophung, 0x0E1C},        // THAI CHARACTER PHO PHUNG
    {XK_Thai_fofa, 0x0E1D},            // THAI CHARACTER FO FA
    {XK_Thai_phophan, 0x0E1E},         // THAI CHARACTER PHO PHAN
    {XK_Thai_fofan, 0x0E1F},           // THAI CHARACTER FO FAN
    {XK_Thai_phosamphao, 0x0E20},      // THAI CHARACTER PHO SAMPHAO
    {XK_Thai_moma, 0x0E21},            // THAI CHARACTER MO MA
    {XK_Thai_yoyak, 0x0E22},           // THAI CHARACTER YO YAK
    {XK_Thai_rorua, 0x0E23},           // THAI CHARACTER RO RUA
    {XK_Thai_ru, 0x0E24},              // THAI CHARACTER RU
    {XK_Thai_loling, 0x0E25},          // THAI CHARACTER LO LING
    {XK_Thai_lu, 0x0E26},              // THAI CHARACTER LU
    {XK_Thai_wowaen, 0x0E27},          // THAI CHARACTER WO WAEN
    {XK_Thai_sosala, 0x0E28},          // THAI CHARACTER SO SALA
    {XK_Thai_sorusi, 0x0E29},          // THAI CHARACTER SO RUSI
    {XK_Thai_sosua, 0x0E2A},           // THAI CHARACTER SO SUA
    {XK_Thai_hohip, 0x0E2B},           // THAI CHARACTER HO HIP
    {XK_Thai_lochula, 0x0E2C},         // THAI CHARACTER LO CHULA
    {XK_Thai_oang, 0x0E2D},            // THAI CHARACTER O ANG
    {XK_Thai_honokhuk, 0x0E2E},        // THAI CHARACTER HO NOKHUK
    {XK_Thai_paiyannoi, 0x0E2F},       // THAI CHARACTER PAIYANNOI
    {XK_Thai_saraa, 0x0E30},           // THAI CHARACTER SARA A
    {XK_Thai_maihanakat, 0x0E31},      // THAI CHARACTER MAI HAN-AKAT
    {XK_Thai_saraaa, 0x0E32},          // THAI CHARACTER SARA AA
    {XK_Thai_saraam, 0x0E33},          // THAI CHARACTER SARA AM
    {XK_Thai_sarai, 0x0E34},           // THAI CHARACTER SARA I
    {XK_Thai_saraii, 0x0E35},          // THAI CHARACTER SARA II
    {XK_Thai_saraue, 0x0E36},          // THAI CHARACTER SARA UE
    {XK_Thai_sarauee, 0x0E37},         // THAI CHARACTER SARA UEE
    {XK_Thai_sarau, 0x0E38},           // THAI CHARACTER SARA U
    {XK_Thai_sarauu, 0x0E39},          // THAI CHARACTER SARA UU
    {XK_Thai_phinthu, 0x0E3A},         // THAI CHARACTER PHINTHU
    {XK_Thai_baht, 0x0E3F},            // THAI CURRENCY SYMBOL BAHT
    {XK_Thai_sarae, 0x0E40},           // THAI CHARACTER SARA E
    {XK_Thai_saraae, 0x0E41},          // THAI CHARACTER SARA AE
    {XK_Thai_sarao, 0x0E42},           // THAI CHARACTER SARA O
    {XK_Thai_saraaimaimuan, 0x0E43},   // THAI CHARACTER SARA AI MAIMUAN
    {XK_Thai_saraaimaimalai, 0x0E44},  // THAI CHARACTER SARA AI MAIMALAI
    {XK_Thai_lakkhangyao, 0x0E45},     // THAI CHARACTER LAKKHANGYAO
    {XK_Thai_maiyamok, 0x0E46},        // THAI CHARACTER MAIYAMOK
    {XK_Thai_maitaikhu, 0x0E47},       // THAI CHARACTER MAITAIKHU
    {XK_Thai_maiek, 0x0E48},           // THAI CHARACTER MAI EK
    {XK_Thai_maitho, 0x0E49},          // THAI CHARACTER MAI THO
    {XK_Thai_maitri, 0x0E4A},          // THAI CHARACTER MAI TRI
    {XK_Thai_maichattawa, 0x0E4B},     // THAI CHARACTER MAI CHATTAWA
    {XK_Thai_thanthakhat, 0x0E4C},     // THAI CHARACTER THANTHAKHAT
    {XK_Thai_nikhahit, 0x0E4D},        // THAI CHARACTER NIKHAHIT
    {XK_Thai_leksun, 0x0E50},          // THAI DIGIT ZERO
    {XK_Thai_leknung, 0x0E51},         // THAI DIGIT ONE
    {XK_Thai_leksong, 0x0E52},         // THAI DIGIT TWO
    {XK_Thai_leksam, 0x0E53},          // THAI DIGIT THREE
    {XK_Thai_leksi, 0x0E54},           // THAI DIGIT FOUR
    {XK_Thai_lekha, 0x0E55},           // THAI DIGIT FIVE
    {XK_Thai_lekhok, 0x0E56},          // THAI DIGIT SIX
    {XK_Thai_lekchet, 0x0E57},         // THAI DIGIT SEVEN
    {XK_Thai_lekpaet, 0x0E58},         // THAI DIGIT EIGHT
    {XK_Thai_lekkao, 0x0E59},          // THAI DIGIT NINE

    // Korean
    {XK_Korean_Won, 0x20A9},  // WON SIGN

    // Armenian KeySyms map 1:1 to Unicode

    // Georgian KeySyms map 1:1 to Unicode

    // Azeri KeySyms map 1:1 to Unicode

    // Vietnamese KeySyms map 1:1 to Unicode

    // Currency KeySyms partially map 1:1 to Unicode
    {XK_EuroSign, 0x20AC},  // EURO SIGN

    // Mathematical KeySyms map 1:1 to Unicode

    // Braille KeySyms map 1:1 to Unicode

    // Sinhala KeySyms map 1:1 to Unicode

    // Dead keys mapped to Unicode combining characters (mostly) for
    // composition,
    // used in combination with the UI Events 'Dead' key. For the X KeySyms that
    // have no combining accent, we use a character whose name has mnemonic
    // value.
    {XK_dead_grave, 0x0300},             // COMBINING GRAVE ACCENT
    {XK_dead_acute, 0x0301},             // COMBINING ACUTE ACCENT
    {XK_dead_circumflex, 0x0302},        // COMBINING CIRCUMFLEX ACCENT
    {XK_dead_tilde, 0x0303},             // COMBINING TILDE
    {XK_dead_macron, 0x0304},            // COMBINING MACRON
    {XK_dead_breve, 0x0306},             // COMBINING BREVE
    {XK_dead_abovedot, 0x0307},          // COMBINING DOT ABOVE
    {XK_dead_diaeresis, 0x0308},         // COMBINING DIAERESIS
    {XK_dead_abovering, 0x030A},         // COMBINING RING ABOVE
    {XK_dead_doubleacute, 0x030B},       // COMBINING DOUBLE ACUTE ACCENT
    {XK_dead_caron, 0x030C},             // COMBINING CARON
    {XK_dead_cedilla, 0x0327},           // COMBINING CEDILLA
    {XK_dead_ogonek, 0x0328},            // COMBINING OGONEK
    {XK_dead_iota, 0x0345},              // COMBINING GREEK YPOGEGRAMMENI
    {XK_dead_voiced_sound, 0x3099},      // COMB. KATAKANA-HIRAGANA VOICED
    {XK_dead_semivoiced_sound, 0x309A},  // COMB. KATAKANA-HIRAGANA SEMI-VOICED
    {XK_dead_belowdot, 0x0323},          // COMBINING DOT BELOW
    {XK_dead_hook, 0x0309},              // COMBINING HOOK ABOVE
    {XK_dead_horn, 0x031B},              // COMBINING HORN
    {XK_dead_stroke, 0x0338},            // COMBINING LONG SOLIDUS OVERLAY
    {XK_dead_abovecomma, 0x0313},        // COMBINING COMMA ABOVE
    {XK_dead_abovereversedcomma, 0x0314},  // COMBINING REVERSED COMMA ABOVE
    {XK_dead_doublegrave, 0x030F},         // COMBINING DOUBLE GRAVE ACCENT
    {XK_dead_belowring, 0x0325},           // COMBINING RING BELOW
    {XK_dead_belowmacron, 0x0331},         // COMBINING MACRON BELOW
    {XK_dead_belowcircumflex, 0x032D},     // COMBINING CIRCUMFLEX ACCENT BELOW
    {XK_dead_belowtilde, 0x0330},          // COMBINING TILDE BELOW
    {XK_dead_belowbreve, 0x032E},          // COMBINING BREVE BELOW
    {XK_dead_belowdiaeresis, 0x0324},      // COMBINING DIAERESIS BELOW
    {XK_dead_invertedbreve, 0x0311},       // COMBINING INVERTED BREVE
    {XK_dead_belowcomma, 0x0326},          // COMBINING COMMA BELOW
    {XK_dead_currency, 0x00A4},            // CURRENCY SIGN
    {XK_dead_greek, 0x037E},               // GREEK QUESTION MARK
});

class KeySymToUnicode {
 public:
  KeySymToUnicode()
      : keysym_to_unicode_map_(std::size(g_keysym_to_unicode_table)) {
    for (size_t i = 0; i < std::size(g_keysym_to_unicode_table); ++i) {
      keysym_to_unicode_map_[g_keysym_to_unicode_table[i].keysym] =
          g_keysym_to_unicode_table[i].unicode;
    }
  }

  KeySymToUnicode(const KeySymToUnicode&) = delete;
  KeySymToUnicode& operator=(const KeySymToUnicode&) = delete;

  uint16_t UnicodeFromKeySym(uint32_t keysym) const {
    // Latin-1 characters have the same representation.
    if ((0x0020 <= keysym && keysym <= 0x007e) ||
        (0x00a0 <= keysym && keysym <= 0x00ff))
      return static_cast<uint16_t>(keysym);

    // Unicode-style KeySyms.
    if ((keysym & 0xffe00000) == 0x01000000) {
      uint32_t unicode = static_cast<uint32_t>(keysym & 0x1fffff);
      if (unicode & ~0xffff)
        return 0;  // We don't support characters outside the Basic Plane.
      return static_cast<uint16_t>(unicode);
    }

    // Other KeySyms which are not Unicode-style.
    auto i = keysym_to_unicode_map_.find(keysym);
    return i != keysym_to_unicode_map_.end() ? i->second : 0;
  }

 private:
  typedef std::unordered_map<uint32_t, uint16_t> KeySymToUnicodeMap;
  KeySymToUnicodeMap keysym_to_unicode_map_;
};

const KeySymToUnicode& GetKeySymToUnicode() {
  static base::NoDestructor<KeySymToUnicode> keysym_to_unicode;
  return *keysym_to_unicode;
}

uint16_t GetUnicodeCharacterFromXKeySym(unsigned long keysym) {
  return GetKeySymToUnicode().UnicodeFromKeySym(static_cast<uint32_t>(keysym));
}

}  // namespace ui