Home | History | Annotate | Download | only in linux
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "remoting/host/linux/unicode_to_keysym.h"
      6 
      7 #include <algorithm>
      8 #define XK_MISCELLANY
      9 #define XK_XKB_KEYS
     10 #define XK_LATIN1
     11 #define XK_LATIN2
     12 #define XK_LATIN3
     13 #define XK_LATIN4
     14 #define XK_LATIN9
     15 #define XK_GREEK
     16 #define XK_KATAKANA
     17 #define XK_ARABIC
     18 #define XK_CYRILLIC
     19 #define XK_HEBREW
     20 #define XK_THAI
     21 #define XK_KOREAN
     22 #define XK_CURRENCY
     23 #define XK_TECHNICAL
     24 #define XK_PUBLISHING
     25 #define XK_APL
     26 #define XK_SPECIAL
     27 #include <X11/keysymdef.h>
     28 
     29 #include "base/macros.h"
     30 
     31 namespace remoting {
     32 
     33 namespace {
     34 
     35 struct CodePair {
     36   int keysym;
     37   uint32_t unicode;
     38 };
     39 
     40 // The table has been sorted by the second column so it can be searched using
     41 // binary search. There might be multiple present keysyms for the same unicode
     42 // value (e.g. see XK_Tab and XK_KP_Tab). It excludes Latin1 characters (which
     43 // have 1-to-1 mapping between keysym and unicode), but includes some
     44 // alternative keysyms for some of them (e.g. XK_KP_0 for '0').
     45 const CodePair kKeySymUnicodeMap[] = {
     46   { XK_BackSpace,                   0x0008 },
     47   { XK_Tab,                         0x0009 },
     48   { XK_KP_Tab,                      0x0009 },
     49   { XK_Return,                      0x000a },
     50   { XK_Escape,                      0x001b },
     51   { XK_KP_Multiply,                 0x002a },
     52   { XK_KP_Add,                      0x002b },
     53   { XK_KP_Separator,                0x002c },
     54   { XK_KP_Subtract,                 0x002d },
     55   { XK_KP_Decimal,                  0x002e },
     56   { XK_KP_Divide,                   0x002f },
     57   { XK_KP_0,                        0x0030 },
     58   { XK_KP_1,                        0x0031 },
     59   { XK_KP_2,                        0x0032 },
     60   { XK_KP_3,                        0x0033 },
     61   { XK_KP_4,                        0x0034 },
     62   { XK_KP_5,                        0x0035 },
     63   { XK_KP_6,                        0x0036 },
     64   { XK_KP_7,                        0x0037 },
     65   { XK_KP_8,                        0x0038 },
     66   { XK_KP_9,                        0x0039 },
     67   { XK_leftcaret,                   0x003c },
     68   { XK_KP_Equal,                    0x003d },
     69   { XK_rightcaret,                  0x003e },
     70   { XK_underbar,                    0x005f },
     71   { XK_Delete,                      0x007f },
     72   { XK_overbar,                     0x00af },
     73   { XK_Amacron,                     0x0100 },
     74   { XK_amacron,                     0x0101 },
     75   { XK_Abreve,                      0x0102 },
     76   { XK_abreve,                      0x0103 },
     77   { XK_Aogonek,                     0x0104 },
     78   { XK_aogonek,                     0x0105 },
     79   { XK_Cacute,                      0x0106 },
     80   { XK_cacute,                      0x0107 },
     81   { XK_Ccircumflex,                 0x0108 },
     82   { XK_ccircumflex,                 0x0109 },
     83   { XK_Cabovedot,                   0x010a },
     84   { XK_cabovedot,                   0x010b },
     85   { XK_Ccaron,                      0x010c },
     86   { XK_ccaron,                      0x010d },
     87   { XK_Dcaron,                      0x010e },
     88   { XK_dcaron,                      0x010f },
     89   { XK_Dstroke,                     0x0110 },
     90   { XK_dstroke,                     0x0111 },
     91   { XK_Emacron,                     0x0112 },
     92   { XK_emacron,                     0x0113 },
     93   { XK_Eabovedot,                   0x0116 },
     94   { XK_eabovedot,                   0x0117 },
     95   { XK_Eogonek,                     0x0118 },
     96   { XK_eogonek,                     0x0119 },
     97   { XK_Ecaron,                      0x011a },
     98   { XK_ecaron,                      0x011b },
     99   { XK_Gcircumflex,                 0x011c },
    100   { XK_gcircumflex,                 0x011d },
    101   { XK_Gbreve,                      0x011e },
    102   { XK_gbreve,                      0x011f },
    103   { XK_Gabovedot,                   0x0120 },
    104   { XK_gabovedot,                   0x0121 },
    105   { XK_Gcedilla,                    0x0122 },
    106   { XK_gcedilla,                    0x0123 },
    107   { XK_Hcircumflex,                 0x0124 },
    108   { XK_hcircumflex,                 0x0125 },
    109   { XK_Hstroke,                     0x0126 },
    110   { XK_hstroke,                     0x0127 },
    111   { XK_Itilde,                      0x0128 },
    112   { XK_itilde,                      0x0129 },
    113   { XK_Imacron,                     0x012a },
    114   { XK_imacron,                     0x012b },
    115   { XK_Iogonek,                     0x012e },
    116   { XK_iogonek,                     0x012f },
    117   { XK_Iabovedot,                   0x0130 },
    118   { XK_idotless,                    0x0131 },
    119   { XK_Jcircumflex,                 0x0134 },
    120   { XK_jcircumflex,                 0x0135 },
    121   { XK_Kcedilla,                    0x0136 },
    122   { XK_kcedilla,                    0x0137 },
    123   { XK_kra,                         0x0138 },
    124   { XK_Lacute,                      0x0139 },
    125   { XK_lacute,                      0x013a },
    126   { XK_Lcedilla,                    0x013b },
    127   { XK_lcedilla,                    0x013c },
    128   { XK_Lcaron,                      0x013d },
    129   { XK_lcaron,                      0x013e },
    130   { XK_Lstroke,                     0x0141 },
    131   { XK_lstroke,                     0x0142 },
    132   { XK_Nacute,                      0x0143 },
    133   { XK_nacute,                      0x0144 },
    134   { XK_Ncedilla,                    0x0145 },
    135   { XK_ncedilla,                    0x0146 },
    136   { XK_Ncaron,                      0x0147 },
    137   { XK_ncaron,                      0x0148 },
    138   { XK_ENG,                         0x014a },
    139   { XK_eng,                         0x014b },
    140   { XK_Omacron,                     0x014c },
    141   { XK_omacron,                     0x014d },
    142   { XK_Odoubleacute,                0x0150 },
    143   { XK_odoubleacute,                0x0151 },
    144   { XK_OE,                          0x0152 },
    145   { XK_oe,                          0x0153 },
    146   { XK_Racute,                      0x0154 },
    147   { XK_racute,                      0x0155 },
    148   { XK_Rcedilla,                    0x0156 },
    149   { XK_rcedilla,                    0x0157 },
    150   { XK_Rcaron,                      0x0158 },
    151   { XK_rcaron,                      0x0159 },
    152   { XK_Sacute,                      0x015a },
    153   { XK_sacute,                      0x015b },
    154   { XK_Scircumflex,                 0x015c },
    155   { XK_scircumflex,                 0x015d },
    156   { XK_Scedilla,                    0x015e },
    157   { XK_scedilla,                    0x015f },
    158   { XK_Scaron,                      0x0160 },
    159   { XK_scaron,                      0x0161 },
    160   { XK_Tcedilla,                    0x0162 },
    161   { XK_tcedilla,                    0x0163 },
    162   { XK_Tcaron,                      0x0164 },
    163   { XK_tcaron,                      0x0165 },
    164   { XK_Tslash,                      0x0166 },
    165   { XK_tslash,                      0x0167 },
    166   { XK_Utilde,                      0x0168 },
    167   { XK_utilde,                      0x0169 },
    168   { XK_Umacron,                     0x016a },
    169   { XK_umacron,                     0x016b },
    170   { XK_Ubreve,                      0x016c },
    171   { XK_ubreve,                      0x016d },
    172   { XK_Uring,                       0x016e },
    173   { XK_uring,                       0x016f },
    174   { XK_Udoubleacute,                0x0170 },
    175   { XK_udoubleacute,                0x0171 },
    176   { XK_Uogonek,                     0x0172 },
    177   { XK_uogonek,                     0x0173 },
    178   { XK_Ydiaeresis,                  0x0178 },
    179   { XK_Zacute,                      0x0179 },
    180   { XK_zacute,                      0x017a },
    181   { XK_Zabovedot,                   0x017b },
    182   { XK_zabovedot,                   0x017c },
    183   { XK_Zcaron,                      0x017d },
    184   { XK_zcaron,                      0x017e },
    185   { XK_function,                    0x0192 },
    186   { XK_caron,                       0x02c7 },
    187   { XK_breve,                       0x02d8 },
    188   { XK_abovedot,                    0x02d9 },
    189   { XK_ogonek,                      0x02db },
    190   { XK_doubleacute,                 0x02dd },
    191   { XK_Greek_accentdieresis,        0x0385 },
    192   { XK_Greek_ALPHAaccent,           0x0386 },
    193   { XK_Greek_EPSILONaccent,         0x0388 },
    194   { XK_Greek_ETAaccent,             0x0389 },
    195   { XK_Greek_IOTAaccent,            0x038a },
    196   { XK_Greek_OMICRONaccent,         0x038c },
    197   { XK_Greek_UPSILONaccent,         0x038e },
    198   { XK_Greek_OMEGAaccent,           0x038f },
    199   { XK_Greek_iotaaccentdieresis,    0x0390 },
    200   { XK_Greek_ALPHA,                 0x0391 },
    201   { XK_Greek_BETA,                  0x0392 },
    202   { XK_Greek_GAMMA,                 0x0393 },
    203   { XK_Greek_DELTA,                 0x0394 },
    204   { XK_Greek_EPSILON,               0x0395 },
    205   { XK_Greek_ZETA,                  0x0396 },
    206   { XK_Greek_ETA,                   0x0397 },
    207   { XK_Greek_THETA,                 0x0398 },
    208   { XK_Greek_IOTA,                  0x0399 },
    209   { XK_Greek_KAPPA,                 0x039a },
    210   { XK_Greek_LAMDA,                 0x039b },
    211   { XK_Greek_MU,                    0x039c },
    212   { XK_Greek_NU,                    0x039d },
    213   { XK_Greek_XI,                    0x039e },
    214   { XK_Greek_OMICRON,               0x039f },
    215   { XK_Greek_PI,                    0x03a0 },
    216   { XK_Greek_RHO,                   0x03a1 },
    217   { XK_Greek_SIGMA,                 0x03a3 },
    218   { XK_Greek_TAU,                   0x03a4 },
    219   { XK_Greek_UPSILON,               0x03a5 },
    220   { XK_Greek_PHI,                   0x03a6 },
    221   { XK_Greek_CHI,                   0x03a7 },
    222   { XK_Greek_PSI,                   0x03a8 },
    223   { XK_Greek_OMEGA,                 0x03a9 },
    224   { XK_Greek_IOTAdiaeresis,         0x03aa },
    225   { XK_Greek_UPSILONdieresis,       0x03ab },
    226   { XK_Greek_alphaaccent,           0x03ac },
    227   { XK_Greek_epsilonaccent,         0x03ad },
    228   { XK_Greek_etaaccent,             0x03ae },
    229   { XK_Greek_iotaaccent,            0x03af },
    230   { XK_Greek_upsilonaccentdieresis, 0x03b0 },
    231   { XK_Greek_alpha,                 0x03b1 },
    232   { XK_Greek_beta,                  0x03b2 },
    233   { XK_Greek_gamma,                 0x03b3 },
    234   { XK_Greek_delta,                 0x03b4 },
    235   { XK_Greek_epsilon,               0x03b5 },
    236   { XK_Greek_zeta,                  0x03b6 },
    237   { XK_Greek_eta,                   0x03b7 },
    238   { XK_Greek_theta,                 0x03b8 },
    239   { XK_Greek_iota,                  0x03b9 },
    240   { XK_Greek_kappa,                 0x03ba },
    241   { XK_Greek_lamda,                 0x03bb },
    242   { XK_Greek_mu,                    0x03bc },
    243   { XK_Greek_nu,                    0x03bd },
    244   { XK_Greek_xi,                    0x03be },
    245   { XK_Greek_omicron,               0x03bf },
    246   { XK_Greek_pi,                    0x03c0 },
    247   { XK_Greek_rho,                   0x03c1 },
    248   { XK_Greek_finalsmallsigma,       0x03c2 },
    249   { XK_Greek_sigma,                 0x03c3 },
    250   { XK_Greek_tau,                   0x03c4 },
    251   { XK_Greek_upsilon,               0x03c5 },
    252   { XK_Greek_phi,                   0x03c6 },
    253   { XK_Greek_chi,                   0x03c7 },
    254   { XK_Greek_psi,                   0x03c8 },
    255   { XK_Greek_omega,                 0x03c9 },
    256   { XK_Greek_iotadieresis,          0x03ca },
    257   { XK_Greek_upsilondieresis,       0x03cb },
    258   { XK_Greek_omicronaccent,         0x03cc },
    259   { XK_Greek_upsilonaccent,         0x03cd },
    260   { XK_Greek_omegaaccent,           0x03ce },
    261   { XK_Cyrillic_IO,                 0x0401 },
    262   { XK_Serbian_DJE,                 0x0402 },
    263   { XK_Macedonia_GJE,               0x0403 },
    264   { XK_Ukrainian_IE,                0x0404 },
    265   { XK_Macedonia_DSE,               0x0405 },
    266   { XK_Ukrainian_I,                 0x0406 },
    267   { XK_Ukrainian_YI,                0x0407 },
    268   { XK_Cyrillic_JE,                 0x0408 },
    269   { XK_Cyrillic_LJE,                0x0409 },
    270   { XK_Cyrillic_NJE,                0x040a },
    271   { XK_Serbian_TSHE,                0x040b },
    272   { XK_Macedonia_KJE,               0x040c },
    273   { XK_Byelorussian_SHORTU,         0x040e },
    274   { XK_Cyrillic_DZHE,               0x040f },
    275   { XK_Cyrillic_A,                  0x0410 },
    276   { XK_Cyrillic_BE,                 0x0411 },
    277   { XK_Cyrillic_VE,                 0x0412 },
    278   { XK_Cyrillic_GHE,                0x0413 },
    279   { XK_Cyrillic_DE,                 0x0414 },
    280   { XK_Cyrillic_IE,                 0x0415 },
    281   { XK_Cyrillic_ZHE,                0x0416 },
    282   { XK_Cyrillic_ZE,                 0x0417 },
    283   { XK_Cyrillic_I,                  0x0418 },
    284   { XK_Cyrillic_SHORTI,             0x0419 },
    285   { XK_Cyrillic_KA,                 0x041a },
    286   { XK_Cyrillic_EL,                 0x041b },
    287   { XK_Cyrillic_EM,                 0x041c },
    288   { XK_Cyrillic_EN,                 0x041d },
    289   { XK_Cyrillic_O,                  0x041e },
    290   { XK_Cyrillic_PE,                 0x041f },
    291   { XK_Cyrillic_ER,                 0x0420 },
    292   { XK_Cyrillic_ES,                 0x0421 },
    293   { XK_Cyrillic_TE,                 0x0422 },
    294   { XK_Cyrillic_U,                  0x0423 },
    295   { XK_Cyrillic_EF,                 0x0424 },
    296   { XK_Cyrillic_HA,                 0x0425 },
    297   { XK_Cyrillic_TSE,                0x0426 },
    298   { XK_Cyrillic_CHE,                0x0427 },
    299   { XK_Cyrillic_SHA,                0x0428 },
    300   { XK_Cyrillic_SHCHA,              0x0429 },
    301   { XK_Cyrillic_HARDSIGN,           0x042a },
    302   { XK_Cyrillic_YERU,               0x042b },
    303   { XK_Cyrillic_SOFTSIGN,           0x042c },
    304   { XK_Cyrillic_E,                  0x042d },
    305   { XK_Cyrillic_YU,                 0x042e },
    306   { XK_Cyrillic_YA,                 0x042f },
    307   { XK_Cyrillic_a,                  0x0430 },
    308   { XK_Cyrillic_be,                 0x0431 },
    309   { XK_Cyrillic_ve,                 0x0432 },
    310   { XK_Cyrillic_ghe,                0x0433 },
    311   { XK_Cyrillic_de,                 0x0434 },
    312   { XK_Cyrillic_ie,                 0x0435 },
    313   { XK_Cyrillic_zhe,                0x0436 },
    314   { XK_Cyrillic_ze,                 0x0437 },
    315   { XK_Cyrillic_i,                  0x0438 },
    316   { XK_Cyrillic_shorti,             0x0439 },
    317   { XK_Cyrillic_ka,                 0x043a },
    318   { XK_Cyrillic_el,                 0x043b },
    319   { XK_Cyrillic_em,                 0x043c },
    320   { XK_Cyrillic_en,                 0x043d },
    321   { XK_Cyrillic_o,                  0x043e },
    322   { XK_Cyrillic_pe,                 0x043f },
    323   { XK_Cyrillic_er,                 0x0440 },
    324   { XK_Cyrillic_es,                 0x0441 },
    325   { XK_Cyrillic_te,                 0x0442 },
    326   { XK_Cyrillic_u,                  0x0443 },
    327   { XK_Cyrillic_ef,                 0x0444 },
    328   { XK_Cyrillic_ha,                 0x0445 },
    329   { XK_Cyrillic_tse,                0x0446 },
    330   { XK_Cyrillic_che,                0x0447 },
    331   { XK_Cyrillic_sha,                0x0448 },
    332   { XK_Cyrillic_shcha,              0x0449 },
    333   { XK_Cyrillic_hardsign,           0x044a },
    334   { XK_Cyrillic_yeru,               0x044b },
    335   { XK_Cyrillic_softsign,           0x044c },
    336   { XK_Cyrillic_e,                  0x044d },
    337   { XK_Cyrillic_yu,                 0x044e },
    338   { XK_Cyrillic_ya,                 0x044f },
    339   { XK_Cyrillic_io,                 0x0451 },
    340   { XK_Serbian_dje,                 0x0452 },
    341   { XK_Macedonia_gje,               0x0453 },
    342   { XK_Ukrainian_ie,                0x0454 },
    343   { XK_Macedonia_dse,               0x0455 },
    344   { XK_Ukrainian_i,                 0x0456 },
    345   { XK_Ukrainian_yi,                0x0457 },
    346   { XK_Cyrillic_je,                 0x0458 },
    347   { XK_Cyrillic_lje,                0x0459 },
    348   { XK_Cyrillic_nje,                0x045a },
    349   { XK_Serbian_tshe,                0x045b },
    350   { XK_Macedonia_kje,               0x045c },
    351   { XK_Byelorussian_shortu,         0x045e },
    352   { XK_Cyrillic_dzhe,               0x045f },
    353   { XK_hebrew_aleph,                0x05d0 },
    354   { XK_hebrew_bet,                  0x05d1 },
    355   { XK_hebrew_gimel,                0x05d2 },
    356   { XK_hebrew_dalet,                0x05d3 },
    357   { XK_hebrew_he,                   0x05d4 },
    358   { XK_hebrew_waw,                  0x05d5 },
    359   { XK_hebrew_zain,                 0x05d6 },
    360   { XK_hebrew_chet,                 0x05d7 },
    361   { XK_hebrew_tet,                  0x05d8 },
    362   { XK_hebrew_yod,                  0x05d9 },
    363   { XK_hebrew_finalkaph,            0x05da },
    364   { XK_hebrew_kaph,                 0x05db },
    365   { XK_hebrew_lamed,                0x05dc },
    366   { XK_hebrew_finalmem,             0x05dd },
    367   { XK_hebrew_mem,                  0x05de },
    368   { XK_hebrew_finalnun,             0x05df },
    369   { XK_hebrew_nun,                  0x05e0 },
    370   { XK_hebrew_samech,               0x05e1 },
    371   { XK_hebrew_ayin,                 0x05e2 },
    372   { XK_hebrew_finalpe,              0x05e3 },
    373   { XK_hebrew_pe,                   0x05e4 },
    374   { XK_hebrew_finalzade,            0x05e5 },
    375   { XK_hebrew_zade,                 0x05e6 },
    376   { XK_hebrew_qoph,                 0x05e7 },
    377   { XK_hebrew_resh,                 0x05e8 },
    378   { XK_hebrew_shin,                 0x05e9 },
    379   { XK_hebrew_taw,                  0x05ea },
    380   { XK_Arabic_comma,                0x060c },
    381   { XK_Arabic_semicolon,            0x061b },
    382   { XK_Arabic_question_mark,        0x061f },
    383   { XK_Arabic_hamza,                0x0621 },
    384   { XK_Arabic_maddaonalef,          0x0622 },
    385   { XK_Arabic_hamzaonalef,          0x0623 },
    386   { XK_Arabic_hamzaonwaw,           0x0624 },
    387   { XK_Arabic_hamzaunderalef,       0x0625 },
    388   { XK_Arabic_hamzaonyeh,           0x0626 },
    389   { XK_Arabic_alef,                 0x0627 },
    390   { XK_Arabic_beh,                  0x0628 },
    391   { XK_Arabic_tehmarbuta,           0x0629 },
    392   { XK_Arabic_teh,                  0x062a },
    393   { XK_Arabic_theh,                 0x062b },
    394   { XK_Arabic_jeem,                 0x062c },
    395   { XK_Arabic_hah,                  0x062d },
    396   { XK_Arabic_khah,                 0x062e },
    397   { XK_Arabic_dal,                  0x062f },
    398   { XK_Arabic_thal,                 0x0630 },
    399   { XK_Arabic_ra,                   0x0631 },
    400   { XK_Arabic_zain,                 0x0632 },
    401   { XK_Arabic_seen,                 0x0633 },
    402   { XK_Arabic_sheen,                0x0634 },
    403   { XK_Arabic_sad,                  0x0635 },
    404   { XK_Arabic_dad,                  0x0636 },
    405   { XK_Arabic_tah,                  0x0637 },
    406   { XK_Arabic_zah,                  0x0638 },
    407   { XK_Arabic_ain,                  0x0639 },
    408   { XK_Arabic_ghain,                0x063a },
    409   { XK_Arabic_tatweel,              0x0640 },
    410   { XK_Arabic_feh,                  0x0641 },
    411   { XK_Arabic_qaf,                  0x0642 },
    412   { XK_Arabic_kaf,                  0x0643 },
    413   { XK_Arabic_lam,                  0x0644 },
    414   { XK_Arabic_meem,                 0x0645 },
    415   { XK_Arabic_noon,                 0x0646 },
    416   { XK_Arabic_ha,                   0x0647 },
    417   { XK_Arabic_waw,                  0x0648 },
    418   { XK_Arabic_alefmaksura,          0x0649 },
    419   { XK_Arabic_yeh,                  0x064a },
    420   { XK_Arabic_fathatan,             0x064b },
    421   { XK_Arabic_dammatan,             0x064c },
    422   { XK_Arabic_kasratan,             0x064d },
    423   { XK_Arabic_fatha,                0x064e },
    424   { XK_Arabic_damma,                0x064f },
    425   { XK_Arabic_kasra,                0x0650 },
    426   { XK_Arabic_shadda,               0x0651 },
    427   { XK_Arabic_sukun,                0x0652 },
    428   { XK_Thai_kokai,                  0x0e01 },
    429   { XK_Thai_khokhai,                0x0e02 },
    430   { XK_Thai_khokhuat,               0x0e03 },
    431   { XK_Thai_khokhwai,               0x0e04 },
    432   { XK_Thai_khokhon,                0x0e05 },
    433   { XK_Thai_khorakhang,             0x0e06 },
    434   { XK_Thai_ngongu,                 0x0e07 },
    435   { XK_Thai_chochan,                0x0e08 },
    436   { XK_Thai_choching,               0x0e09 },
    437   { XK_Thai_chochang,               0x0e0a },
    438   { XK_Thai_soso,                   0x0e0b },
    439   { XK_Thai_chochoe,                0x0e0c },
    440   { XK_Thai_yoying,                 0x0e0d },
    441   { XK_Thai_dochada,                0x0e0e },
    442   { XK_Thai_topatak,                0x0e0f },
    443   { XK_Thai_thothan,                0x0e10 },
    444   { XK_Thai_thonangmontho,          0x0e11 },
    445   { XK_Thai_thophuthao,             0x0e12 },
    446   { XK_Thai_nonen,                  0x0e13 },
    447   { XK_Thai_dodek,                  0x0e14 },
    448   { XK_Thai_totao,                  0x0e15 },
    449   { XK_Thai_thothung,               0x0e16 },
    450   { XK_Thai_thothahan,              0x0e17 },
    451   { XK_Thai_thothong,               0x0e18 },
    452   { XK_Thai_nonu,                   0x0e19 },
    453   { XK_Thai_bobaimai,               0x0e1a },
    454   { XK_Thai_popla,                  0x0e1b },
    455   { XK_Thai_phophung,               0x0e1c },
    456   { XK_Thai_fofa,                   0x0e1d },
    457   { XK_Thai_phophan,                0x0e1e },
    458   { XK_Thai_fofan,                  0x0e1f },
    459   { XK_Thai_phosamphao,             0x0e20 },
    460   { XK_Thai_moma,                   0x0e21 },
    461   { XK_Thai_yoyak,                  0x0e22 },
    462   { XK_Thai_rorua,                  0x0e23 },
    463   { XK_Thai_ru,                     0x0e24 },
    464   { XK_Thai_loling,                 0x0e25 },
    465   { XK_Thai_lu,                     0x0e26 },
    466   { XK_Thai_wowaen,                 0x0e27 },
    467   { XK_Thai_sosala,                 0x0e28 },
    468   { XK_Thai_sorusi,                 0x0e29 },
    469   { XK_Thai_sosua,                  0x0e2a },
    470   { XK_Thai_hohip,                  0x0e2b },
    471   { XK_Thai_lochula,                0x0e2c },
    472   { XK_Thai_oang,                   0x0e2d },
    473   { XK_Thai_honokhuk,               0x0e2e },
    474   { XK_Thai_paiyannoi,              0x0e2f },
    475   { XK_Thai_saraa,                  0x0e30 },
    476   { XK_Thai_maihanakat,             0x0e31 },
    477   { XK_Thai_saraaa,                 0x0e32 },
    478   { XK_Thai_saraam,                 0x0e33 },
    479   { XK_Thai_sarai,                  0x0e34 },
    480   { XK_Thai_saraii,                 0x0e35 },
    481   { XK_Thai_saraue,                 0x0e36 },
    482   { XK_Thai_sarauee,                0x0e37 },
    483   { XK_Thai_sarau,                  0x0e38 },
    484   { XK_Thai_sarauu,                 0x0e39 },
    485   { XK_Thai_phinthu,                0x0e3a },
    486   { XK_Thai_baht,                   0x0e3f },
    487   { XK_Thai_sarae,                  0x0e40 },
    488   { XK_Thai_saraae,                 0x0e41 },
    489   { XK_Thai_sarao,                  0x0e42 },
    490   { XK_Thai_saraaimaimuan,          0x0e43 },
    491   { XK_Thai_saraaimaimalai,         0x0e44 },
    492   { XK_Thai_lakkhangyao,            0x0e45 },
    493   { XK_Thai_maiyamok,               0x0e46 },
    494   { XK_Thai_maitaikhu,              0x0e47 },
    495   { XK_Thai_maiek,                  0x0e48 },
    496   { XK_Thai_maitho,                 0x0e49 },
    497   { XK_Thai_maitri,                 0x0e4a },
    498   { XK_Thai_maichattawa,            0x0e4b },
    499   { XK_Thai_thanthakhat,            0x0e4c },
    500   { XK_Thai_nikhahit,               0x0e4d },
    501   { XK_Thai_leksun,                 0x0e50 },
    502   { XK_Thai_leknung,                0x0e51 },
    503   { XK_Thai_leksong,                0x0e52 },
    504   { XK_Thai_leksam,                 0x0e53 },
    505   { XK_Thai_leksi,                  0x0e54 },
    506   { XK_Thai_lekha,                  0x0e55 },
    507   { XK_Thai_lekhok,                 0x0e56 },
    508   { XK_Thai_lekchet,                0x0e57 },
    509   { XK_Thai_lekpaet,                0x0e58 },
    510   { XK_Thai_lekkao,                 0x0e59 },
    511   { XK_Hangul_J_Kiyeog,             0x11a8 },
    512   { XK_Hangul_J_SsangKiyeog,        0x11a9 },
    513   { XK_Hangul_J_KiyeogSios,         0x11aa },
    514   { XK_Hangul_J_Nieun,              0x11ab },
    515   { XK_Hangul_J_NieunJieuj,         0x11ac },
    516   { XK_Hangul_J_NieunHieuh,         0x11ad },
    517   { XK_Hangul_J_Dikeud,             0x11ae },
    518   { XK_Hangul_J_Rieul,              0x11af },
    519   { XK_Hangul_J_RieulKiyeog,        0x11b0 },
    520   { XK_Hangul_J_RieulMieum,         0x11b1 },
    521   { XK_Hangul_J_RieulPieub,         0x11b2 },
    522   { XK_Hangul_J_RieulSios,          0x11b3 },
    523   { XK_Hangul_J_RieulTieut,         0x11b4 },
    524   { XK_Hangul_J_RieulPhieuf,        0x11b5 },
    525   { XK_Hangul_J_RieulHieuh,         0x11b6 },
    526   { XK_Hangul_J_Mieum,              0x11b7 },
    527   { XK_Hangul_J_Pieub,              0x11b8 },
    528   { XK_Hangul_J_PieubSios,          0x11b9 },
    529   { XK_Hangul_J_Sios,               0x11ba },
    530   { XK_Hangul_J_SsangSios,          0x11bb },
    531   { XK_Hangul_J_Ieung,              0x11bc },
    532   { XK_Hangul_J_Jieuj,              0x11bd },
    533   { XK_Hangul_J_Cieuc,              0x11be },
    534   { XK_Hangul_J_Khieuq,             0x11bf },
    535   { XK_Hangul_J_Tieut,              0x11c0 },
    536   { XK_Hangul_J_Phieuf,             0x11c1 },
    537   { XK_Hangul_J_Hieuh,              0x11c2 },
    538   { XK_Hangul_J_PanSios,            0x11eb },
    539   { XK_Hangul_J_KkogjiDalrinIeung , 0x11f0 },
    540   { XK_Hangul_J_YeorinHieuh,        0x11f9 },
    541   { XK_enspace,                     0x2002 },
    542   { XK_emspace,                     0x2003 },
    543   { XK_em3space,                    0x2004 },
    544   { XK_em4space,                    0x2005 },
    545   { XK_digitspace,                  0x2007 },
    546   { XK_punctspace,                  0x2008 },
    547   { XK_thinspace,                   0x2009 },
    548   { XK_hairspace,                   0x200a },
    549   { XK_figdash,                     0x2012 },
    550   { XK_endash,                      0x2013 },
    551   { XK_emdash,                      0x2014 },
    552   { XK_Greek_horizbar,              0x2015 },
    553   { XK_hebrew_doublelowline,        0x2017 },
    554   { XK_leftsinglequotemark,         0x2018 },
    555   { XK_rightsinglequotemark,        0x2019 },
    556   { XK_singlelowquotemark,          0x201a },
    557   { XK_leftdoublequotemark,         0x201c },
    558   { XK_rightdoublequotemark,        0x201d },
    559   { XK_doublelowquotemark,          0x201e },
    560   { XK_dagger,                      0x2020 },
    561   { XK_doubledagger,                0x2021 },
    562   { XK_enfilledcircbullet,          0x2022 },
    563   { XK_doubbaselinedot,             0x2025 },
    564   { XK_ellipsis,                    0x2026 },
    565   { XK_minutes,                     0x2032 },
    566   { XK_seconds,                     0x2033 },
    567   { XK_caret,                       0x2038 },
    568   { XK_overline,                    0x203e },
    569   { XK_Korean_Won,                  0x20a9 },
    570   { XK_EuroSign,                    0x20ac },
    571   { XK_careof,                      0x2105 },
    572   { XK_numerosign,                  0x2116 },
    573   { XK_phonographcopyright,         0x2117 },
    574   { XK_prescription,                0x211e },
    575   { XK_trademark,                   0x2122 },
    576   { XK_onethird,                    0x2153 },
    577   { XK_twothirds,                   0x2154 },
    578   { XK_onefifth,                    0x2155 },
    579   { XK_twofifths,                   0x2156 },
    580   { XK_threefifths,                 0x2157 },
    581   { XK_fourfifths,                  0x2158 },
    582   { XK_onesixth,                    0x2159 },
    583   { XK_fivesixths,                  0x215a },
    584   { XK_oneeighth,                   0x215b },
    585   { XK_threeeighths,                0x215c },
    586   { XK_fiveeighths,                 0x215d },
    587   { XK_seveneighths,                0x215e },
    588   { XK_leftarrow,                   0x2190 },
    589   { XK_uparrow,                     0x2191 },
    590   { XK_rightarrow,                  0x2192 },
    591   { XK_downarrow,                   0x2193 },
    592   { XK_implies,                     0x21d2 },
    593   { XK_ifonlyif,                    0x21d4 },
    594   { XK_partialderivative,           0x2202 },
    595   { XK_nabla,                       0x2207 },
    596   { XK_jot,                         0x2218 },
    597   { XK_radical,                     0x221a },
    598   { XK_variation,                   0x221d },
    599   { XK_infinity,                    0x221e },
    600   { XK_logicaland,                  0x2227 },
    601   { XK_logicalor,                   0x2228 },
    602   { XK_intersection,                0x2229 },
    603   { XK_union,                       0x222a },
    604   { XK_integral,                    0x222b },
    605   { XK_therefore,                   0x2234 },
    606   { XK_approximate,                 0x223c },
    607   { XK_similarequal,                0x2243 },
    608   { XK_notequal,                    0x2260 },
    609   { XK_identical,                   0x2261 },
    610   { XK_lessthanequal,               0x2264 },
    611   { XK_greaterthanequal,            0x2265 },
    612   { XK_includedin,                  0x2282 },
    613   { XK_includes,                    0x2283 },
    614   { XK_righttack,                   0x22a2 },
    615   { XK_lefttack,                    0x22a3 },
    616   { XK_uptack,                      0x22a4 },
    617   { XK_downtack,                    0x22a5 },
    618   { XK_upstile,                     0x2308 },
    619   { XK_downstile,                   0x230a },
    620   { XK_telephonerecorder,           0x2315 },
    621   { XK_topintegral,                 0x2320 },
    622   { XK_botintegral,                 0x2321 },
    623   { XK_leftanglebracket,            0x2329 },
    624   { XK_rightanglebracket,           0x232a },
    625   { XK_quad,                        0x2395 },
    626   { XK_topleftparens,               0x239b },
    627   { XK_botleftparens,               0x239d },
    628   { XK_toprightparens,              0x239e },
    629   { XK_botrightparens,              0x23a0 },
    630   { XK_topleftsqbracket,            0x23a1 },
    631   { XK_botleftsqbracket,            0x23a3 },
    632   { XK_toprightsqbracket,           0x23a4 },
    633   { XK_botrightsqbracket,           0x23a6 },
    634   { XK_leftmiddlecurlybrace,        0x23a8 },
    635   { XK_rightmiddlecurlybrace,       0x23ac },
    636   { XK_leftradical,                 0x23b7 },
    637   { XK_horizlinescan1,              0x23ba },
    638   { XK_horizlinescan3,              0x23bb },
    639   { XK_horizlinescan7,              0x23bc },
    640   { XK_horizlinescan9,              0x23bd },
    641   { XK_ht,                          0x2409 },
    642   { XK_lf,                          0x240a },
    643   { XK_vt,                          0x240b },
    644   { XK_ff,                          0x240c },
    645   { XK_cr,                          0x240d },
    646   { XK_nl,                          0x2424 },
    647   { XK_horizlinescan5,              0x2500 },
    648   { XK_vertbar,                     0x2502 },
    649   { XK_upleftcorner,                0x250c },
    650   { XK_uprightcorner,               0x2510 },
    651   { XK_lowleftcorner,               0x2514 },
    652   { XK_lowrightcorner,              0x2518 },
    653   { XK_leftt,                       0x251c },
    654   { XK_rightt,                      0x2524 },
    655   { XK_topt,                        0x252c },
    656   { XK_bott,                        0x2534 },
    657   { XK_crossinglines,               0x253c },
    658   { XK_checkerboard,                0x2592 },
    659   { XK_enfilledsqbullet,            0x25aa },
    660   { XK_enopensquarebullet,          0x25ab },
    661   { XK_filledrectbullet,            0x25ac },
    662   { XK_openrectbullet,              0x25ad },
    663   { XK_emfilledrect,                0x25ae },
    664   { XK_emopenrectangle,             0x25af },
    665   { XK_filledtribulletup,           0x25b2 },
    666   { XK_opentribulletup,             0x25b3 },
    667   { XK_filledrighttribullet,        0x25b6 },
    668   { XK_rightopentriangle,           0x25b7 },
    669   { XK_filledtribulletdown,         0x25bc },
    670   { XK_opentribulletdown,           0x25bd },
    671   { XK_filledlefttribullet,         0x25c0 },
    672   { XK_leftopentriangle,            0x25c1 },
    673   { XK_soliddiamond,                0x25c6 },
    674   { XK_emopencircle,                0x25cb },
    675   { XK_emfilledcircle,              0x25cf },
    676   { XK_enopencircbullet,            0x25e6 },
    677   { XK_openstar,                    0x2606 },
    678   { XK_telephone,                   0x260e },
    679   { XK_signaturemark,               0x2613 },
    680   { XK_leftpointer,                 0x261c },
    681   { XK_rightpointer,                0x261e },
    682   { XK_femalesymbol,                0x2640 },
    683   { XK_malesymbol,                  0x2642 },
    684   { XK_club,                        0x2663 },
    685   { XK_heart,                       0x2665 },
    686   { XK_diamond,                     0x2666 },
    687   { XK_musicalflat,                 0x266d },
    688   { XK_musicalsharp,                0x266f },
    689   { XK_checkmark,                   0x2713 },
    690   { XK_ballotcross,                 0x2717 },
    691   { XK_latincross,                  0x271d },
    692   { XK_maltesecross,                0x2720 },
    693   { XK_kana_comma,                  0x3001 },
    694   { XK_kana_fullstop,               0x3002 },
    695   { XK_kana_openingbracket,         0x300c },
    696   { XK_kana_closingbracket,         0x300d },
    697   { XK_voicedsound,                 0x309b },
    698   { XK_semivoicedsound,             0x309c },
    699   { XK_kana_a,                      0x30a1 },
    700   { XK_kana_A,                      0x30a2 },
    701   { XK_kana_i,                      0x30a3 },
    702   { XK_kana_I,                      0x30a4 },
    703   { XK_kana_u,                      0x30a5 },
    704   { XK_kana_U,                      0x30a6 },
    705   { XK_kana_e,                      0x30a7 },
    706   { XK_kana_E,                      0x30a8 },
    707   { XK_kana_o,                      0x30a9 },
    708   { XK_kana_O,                      0x30aa },
    709   { XK_kana_KA,                     0x30ab },
    710   { XK_kana_KI,                     0x30ad },
    711   { XK_kana_KU,                     0x30af },
    712   { XK_kana_KE,                     0x30b1 },
    713   { XK_kana_KO,                     0x30b3 },
    714   { XK_kana_SA,                     0x30b5 },
    715   { XK_kana_SHI,                    0x30b7 },
    716   { XK_kana_SU,                     0x30b9 },
    717   { XK_kana_SE,                     0x30bb },
    718   { XK_kana_SO,                     0x30bd },
    719   { XK_kana_TA,                     0x30bf },
    720   { XK_kana_CHI,                    0x30c1 },
    721   { XK_kana_tsu,                    0x30c3 },
    722   { XK_kana_TSU,                    0x30c4 },
    723   { XK_kana_TE,                     0x30c6 },
    724   { XK_kana_TO,                     0x30c8 },
    725   { XK_kana_NA,                     0x30ca },
    726   { XK_kana_NI,                     0x30cb },
    727   { XK_kana_NU,                     0x30cc },
    728   { XK_kana_NE,                     0x30cd },
    729   { XK_kana_NO,                     0x30ce },
    730   { XK_kana_HA,                     0x30cf },
    731   { XK_kana_HI,                     0x30d2 },
    732   { XK_kana_FU,                     0x30d5 },
    733   { XK_kana_HE,                     0x30d8 },
    734   { XK_kana_HO,                     0x30db },
    735   { XK_kana_MA,                     0x30de },
    736   { XK_kana_MI,                     0x30df },
    737   { XK_kana_MU,                     0x30e0 },
    738   { XK_kana_ME,                     0x30e1 },
    739   { XK_kana_MO,                     0x30e2 },
    740   { XK_kana_ya,                     0x30e3 },
    741   { XK_kana_YA,                     0x30e4 },
    742   { XK_kana_yu,                     0x30e5 },
    743   { XK_kana_YU,                     0x30e6 },
    744   { XK_kana_yo,                     0x30e7 },
    745   { XK_kana_YO,                     0x30e8 },
    746   { XK_kana_RA,                     0x30e9 },
    747   { XK_kana_RI,                     0x30ea },
    748   { XK_kana_RU,                     0x30eb },
    749   { XK_kana_RE,                     0x30ec },
    750   { XK_kana_RO,                     0x30ed },
    751   { XK_kana_WA,                     0x30ef },
    752   { XK_kana_WO,                     0x30f2 },
    753   { XK_kana_N,                      0x30f3 },
    754   { XK_kana_conjunctive,            0x30fb },
    755   { XK_prolongedsound,              0x30fc },
    756   { XK_Hangul_Kiyeog,               0x3131 },
    757   { XK_Hangul_SsangKiyeog,          0x3132 },
    758   { XK_Hangul_KiyeogSios,           0x3133 },
    759   { XK_Hangul_Nieun,                0x3134 },
    760   { XK_Hangul_NieunJieuj,           0x3135 },
    761   { XK_Hangul_NieunHieuh,           0x3136 },
    762   { XK_Hangul_Dikeud,               0x3137 },
    763   { XK_Hangul_SsangDikeud,          0x3138 },
    764   { XK_Hangul_Rieul,                0x3139 },
    765   { XK_Hangul_RieulKiyeog,          0x313a },
    766   { XK_Hangul_RieulMieum,           0x313b },
    767   { XK_Hangul_RieulPieub,           0x313c },
    768   { XK_Hangul_RieulSios,            0x313d },
    769   { XK_Hangul_RieulTieut,           0x313e },
    770   { XK_Hangul_RieulPhieuf,          0x313f },
    771   { XK_Hangul_RieulHieuh,           0x3140 },
    772   { XK_Hangul_Mieum,                0x3141 },
    773   { XK_Hangul_Pieub,                0x3142 },
    774   { XK_Hangul_SsangPieub,           0x3143 },
    775   { XK_Hangul_PieubSios,            0x3144 },
    776   { XK_Hangul_Sios,                 0x3145 },
    777   { XK_Hangul_SsangSios,            0x3146 },
    778   { XK_Hangul_Ieung,                0x3147 },
    779   { XK_Hangul_Jieuj,                0x3148 },
    780   { XK_Hangul_SsangJieuj,           0x3149 },
    781   { XK_Hangul_Cieuc,                0x314a },
    782   { XK_Hangul_Khieuq,               0x314b },
    783   { XK_Hangul_Tieut,                0x314c },
    784   { XK_Hangul_Phieuf,               0x314d },
    785   { XK_Hangul_Hieuh,                0x314e },
    786   { XK_Hangul_A,                    0x314f },
    787   { XK_Hangul_AE,                   0x3150 },
    788   { XK_Hangul_YA,                   0x3151 },
    789   { XK_Hangul_YAE,                  0x3152 },
    790   { XK_Hangul_EO,                   0x3153 },
    791   { XK_Hangul_E,                    0x3154 },
    792   { XK_Hangul_YEO,                  0x3155 },
    793   { XK_Hangul_YE,                   0x3156 },
    794   { XK_Hangul_O,                    0x3157 },
    795   { XK_Hangul_WA,                   0x3158 },
    796   { XK_Hangul_WAE,                  0x3159 },
    797   { XK_Hangul_OE,                   0x315a },
    798   { XK_Hangul_YO,                   0x315b },
    799   { XK_Hangul_U,                    0x315c },
    800   { XK_Hangul_WEO,                  0x315d },
    801   { XK_Hangul_WE,                   0x315e },
    802   { XK_Hangul_WI,                   0x315f },
    803   { XK_Hangul_YU,                   0x3160 },
    804   { XK_Hangul_EU,                   0x3161 },
    805   { XK_Hangul_YI,                   0x3162 },
    806   { XK_Hangul_I,                    0x3163 },
    807   { XK_Hangul_RieulYeorinHieuh,     0x316d },
    808   { XK_Hangul_SunkyeongeumMieum,    0x3171 },
    809   { XK_Hangul_SunkyeongeumPieub,    0x3178 },
    810   { XK_Hangul_PanSios,              0x317f },
    811   { XK_Hangul_KkogjiDalrinIeung,    0x3181 },
    812   { XK_Hangul_SunkyeongeumPhieuf,   0x3184 },
    813   { XK_Hangul_YeorinHieuh,          0x3186 },
    814   { XK_Hangul_AraeA,                0x318d },
    815   { XK_Hangul_AraeAE,               0x318e },
    816 };
    817 
    818 bool CompareCodePair(const CodePair& pair, uint32_t unicode) {
    819   return pair.unicode < unicode;
    820 }
    821 
    822 }  // namespace
    823 
    824 void GetKeySymsForUnicode(uint32_t unicode, std::vector<uint32_t>* keysyms) {
    825   keysyms->clear();
    826 
    827   // Latin-1 characters have the same values in Unicode and KeySym.
    828   if ((unicode >= 0x0020 && unicode <= 0x007e) ||
    829       (unicode >= 0x00a0 && unicode <= 0x00ff)) {
    830     keysyms->push_back(unicode);
    831   }
    832 
    833   const CodePair* map_end = kKeySymUnicodeMap + arraysize(kKeySymUnicodeMap);
    834   const CodePair* pair =
    835       std::lower_bound(kKeySymUnicodeMap, map_end, unicode, &CompareCodePair);
    836   while (pair != map_end && pair->unicode == unicode) {
    837     keysyms->push_back(pair->keysym);
    838     ++pair;
    839   }
    840 
    841   keysyms->push_back(0x01000000 | unicode);
    842 }
    843 
    844 }  // namespace remoting
    845