00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CXWindowsUtil.h"
00016 #include "KeyTypes.h"
00017 #include "CThread.h"
00018 #include "CLog.h"
00019 #include "CStringUtil.h"
00020 #include <X11/Xatom.h>
00021 #define XK_APL
00022 #define XK_ARABIC
00023 #define XK_ARMENIAN
00024 #define XK_CAUCASUS
00025 #define XK_CURRENCY
00026 #define XK_CYRILLIC
00027 #define XK_GEORGIAN
00028 #define XK_GREEK
00029 #define XK_HEBREW
00030 #define XK_KATAKANA
00031 #define XK_KOREAN
00032 #define XK_LATIN1
00033 #define XK_LATIN2
00034 #define XK_LATIN3
00035 #define XK_LATIN4
00036 #define XK_LATIN8
00037 #define XK_LATIN9
00038 #define XK_MISCELLANY
00039 #define XK_PUBLISHING
00040 #define XK_SPECIAL
00041 #define XK_TECHNICAL
00042 #define XK_THAI
00043 #define XK_VIETNAMESE
00044 #define XK_XKB_KEYS
00045 #include <X11/keysym.h>
00046
00047 #if !defined(XK_OE)
00048 #define XK_OE 0x13bc
00049 #endif
00050 #if !defined(XK_oe)
00051 #define XK_oe 0x13bd
00052 #endif
00053 #if !defined(XK_Ydiaeresis)
00054 #define XK_Ydiaeresis 0x13be
00055 #endif
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 struct codepair {
00074 KeySym keysym;
00075 UInt32 ucs4;
00076 } s_keymap[] = {
00077 { XK_Aogonek, 0x0104 },
00078 { XK_breve, 0x02d8 },
00079 { XK_Lstroke, 0x0141 },
00080 { XK_Lcaron, 0x013d },
00081 { XK_Sacute, 0x015a },
00082 { XK_Scaron, 0x0160 },
00083 { XK_Scedilla, 0x015e },
00084 { XK_Tcaron, 0x0164 },
00085 { XK_Zacute, 0x0179 },
00086 { XK_Zcaron, 0x017d },
00087 { XK_Zabovedot, 0x017b },
00088 { XK_aogonek, 0x0105 },
00089 { XK_ogonek, 0x02db },
00090 { XK_lstroke, 0x0142 },
00091 { XK_lcaron, 0x013e },
00092 { XK_sacute, 0x015b },
00093 { XK_caron, 0x02c7 },
00094 { XK_scaron, 0x0161 },
00095 { XK_scedilla, 0x015f },
00096 { XK_tcaron, 0x0165 },
00097 { XK_zacute, 0x017a },
00098 { XK_doubleacute, 0x02dd },
00099 { XK_zcaron, 0x017e },
00100 { XK_zabovedot, 0x017c },
00101 { XK_Racute, 0x0154 },
00102 { XK_Abreve, 0x0102 },
00103 { XK_Lacute, 0x0139 },
00104 { XK_Cacute, 0x0106 },
00105 { XK_Ccaron, 0x010c },
00106 { XK_Eogonek, 0x0118 },
00107 { XK_Ecaron, 0x011a },
00108 { XK_Dcaron, 0x010e },
00109 { XK_Dstroke, 0x0110 },
00110 { XK_Nacute, 0x0143 },
00111 { XK_Ncaron, 0x0147 },
00112 { XK_Odoubleacute, 0x0150 },
00113 { XK_Rcaron, 0x0158 },
00114 { XK_Uring, 0x016e },
00115 { XK_Udoubleacute, 0x0170 },
00116 { XK_Tcedilla, 0x0162 },
00117 { XK_racute, 0x0155 },
00118 { XK_abreve, 0x0103 },
00119 { XK_lacute, 0x013a },
00120 { XK_cacute, 0x0107 },
00121 { XK_ccaron, 0x010d },
00122 { XK_eogonek, 0x0119 },
00123 { XK_ecaron, 0x011b },
00124 { XK_dcaron, 0x010f },
00125 { XK_dstroke, 0x0111 },
00126 { XK_nacute, 0x0144 },
00127 { XK_ncaron, 0x0148 },
00128 { XK_odoubleacute, 0x0151 },
00129 { XK_rcaron, 0x0159 },
00130 { XK_uring, 0x016f },
00131 { XK_udoubleacute, 0x0171 },
00132 { XK_tcedilla, 0x0163 },
00133 { XK_abovedot, 0x02d9 },
00134 { XK_Hstroke, 0x0126 },
00135 { XK_Hcircumflex, 0x0124 },
00136 { XK_Iabovedot, 0x0130 },
00137 { XK_Gbreve, 0x011e },
00138 { XK_Jcircumflex, 0x0134 },
00139 { XK_hstroke, 0x0127 },
00140 { XK_hcircumflex, 0x0125 },
00141 { XK_idotless, 0x0131 },
00142 { XK_gbreve, 0x011f },
00143 { XK_jcircumflex, 0x0135 },
00144 { XK_Cabovedot, 0x010a },
00145 { XK_Ccircumflex, 0x0108 },
00146 { XK_Gabovedot, 0x0120 },
00147 { XK_Gcircumflex, 0x011c },
00148 { XK_Ubreve, 0x016c },
00149 { XK_Scircumflex, 0x015c },
00150 { XK_cabovedot, 0x010b },
00151 { XK_ccircumflex, 0x0109 },
00152 { XK_gabovedot, 0x0121 },
00153 { XK_gcircumflex, 0x011d },
00154 { XK_ubreve, 0x016d },
00155 { XK_scircumflex, 0x015d },
00156 { XK_kra, 0x0138 },
00157 { XK_Rcedilla, 0x0156 },
00158 { XK_Itilde, 0x0128 },
00159 { XK_Lcedilla, 0x013b },
00160 { XK_Emacron, 0x0112 },
00161 { XK_Gcedilla, 0x0122 },
00162 { XK_Tslash, 0x0166 },
00163 { XK_rcedilla, 0x0157 },
00164 { XK_itilde, 0x0129 },
00165 { XK_lcedilla, 0x013c },
00166 { XK_emacron, 0x0113 },
00167 { XK_gcedilla, 0x0123 },
00168 { XK_tslash, 0x0167 },
00169 { XK_ENG, 0x014a },
00170 { XK_eng, 0x014b },
00171 { XK_Amacron, 0x0100 },
00172 { XK_Iogonek, 0x012e },
00173 { XK_Eabovedot, 0x0116 },
00174 { XK_Imacron, 0x012a },
00175 { XK_Ncedilla, 0x0145 },
00176 { XK_Omacron, 0x014c },
00177 { XK_Kcedilla, 0x0136 },
00178 { XK_Uogonek, 0x0172 },
00179 { XK_Utilde, 0x0168 },
00180 { XK_Umacron, 0x016a },
00181 { XK_amacron, 0x0101 },
00182 { XK_iogonek, 0x012f },
00183 { XK_eabovedot, 0x0117 },
00184 { XK_imacron, 0x012b },
00185 { XK_ncedilla, 0x0146 },
00186 { XK_omacron, 0x014d },
00187 { XK_kcedilla, 0x0137 },
00188 { XK_uogonek, 0x0173 },
00189 { XK_utilde, 0x0169 },
00190 { XK_umacron, 0x016b },
00191 #if defined(XK_Babovedot)
00192 { XK_Babovedot, 0x1e02 },
00193 { XK_babovedot, 0x1e03 },
00194 { XK_Dabovedot, 0x1e0a },
00195 { XK_Wgrave, 0x1e80 },
00196 { XK_Wacute, 0x1e82 },
00197 { XK_dabovedot, 0x1e0b },
00198 { XK_Ygrave, 0x1ef2 },
00199 { XK_Fabovedot, 0x1e1e },
00200 { XK_fabovedot, 0x1e1f },
00201 { XK_Mabovedot, 0x1e40 },
00202 { XK_mabovedot, 0x1e41 },
00203 { XK_Pabovedot, 0x1e56 },
00204 { XK_wgrave, 0x1e81 },
00205 { XK_pabovedot, 0x1e57 },
00206 { XK_wacute, 0x1e83 },
00207 { XK_Sabovedot, 0x1e60 },
00208 { XK_ygrave, 0x1ef3 },
00209 { XK_Wdiaeresis, 0x1e84 },
00210 { XK_wdiaeresis, 0x1e85 },
00211 { XK_sabovedot, 0x1e61 },
00212 { XK_Wcircumflex, 0x0174 },
00213 { XK_Tabovedot, 0x1e6a },
00214 { XK_Ycircumflex, 0x0176 },
00215 { XK_wcircumflex, 0x0175 },
00216 { XK_tabovedot, 0x1e6b },
00217 { XK_ycircumflex, 0x0177 },
00218 #endif // defined(XK_Babovedot)
00219 #if defined(XK_overline)
00220 { XK_overline, 0x203e },
00221 { XK_kana_fullstop, 0x3002 },
00222 { XK_kana_openingbracket, 0x300c },
00223 { XK_kana_closingbracket, 0x300d },
00224 { XK_kana_comma, 0x3001 },
00225 { XK_kana_conjunctive, 0x30fb },
00226 { XK_kana_WO, 0x30f2 },
00227 { XK_kana_a, 0x30a1 },
00228 { XK_kana_i, 0x30a3 },
00229 { XK_kana_u, 0x30a5 },
00230 { XK_kana_e, 0x30a7 },
00231 { XK_kana_o, 0x30a9 },
00232 { XK_kana_ya, 0x30e3 },
00233 { XK_kana_yu, 0x30e5 },
00234 { XK_kana_yo, 0x30e7 },
00235 { XK_kana_tsu, 0x30c3 },
00236 { XK_prolongedsound, 0x30fc },
00237 { XK_kana_A, 0x30a2 },
00238 { XK_kana_I, 0x30a4 },
00239 { XK_kana_U, 0x30a6 },
00240 { XK_kana_E, 0x30a8 },
00241 { XK_kana_O, 0x30aa },
00242 { XK_kana_KA, 0x30ab },
00243 { XK_kana_KI, 0x30ad },
00244 { XK_kana_KU, 0x30af },
00245 { XK_kana_KE, 0x30b1 },
00246 { XK_kana_KO, 0x30b3 },
00247 { XK_kana_SA, 0x30b5 },
00248 { XK_kana_SHI, 0x30b7 },
00249 { XK_kana_SU, 0x30b9 },
00250 { XK_kana_SE, 0x30bb },
00251 { XK_kana_SO, 0x30bd },
00252 { XK_kana_TA, 0x30bf },
00253 { XK_kana_CHI, 0x30c1 },
00254 { XK_kana_TSU, 0x30c4 },
00255 { XK_kana_TE, 0x30c6 },
00256 { XK_kana_TO, 0x30c8 },
00257 { XK_kana_NA, 0x30ca },
00258 { XK_kana_NI, 0x30cb },
00259 { XK_kana_NU, 0x30cc },
00260 { XK_kana_NE, 0x30cd },
00261 { XK_kana_NO, 0x30ce },
00262 { XK_kana_HA, 0x30cf },
00263 { XK_kana_HI, 0x30d2 },
00264 { XK_kana_FU, 0x30d5 },
00265 { XK_kana_HE, 0x30d8 },
00266 { XK_kana_HO, 0x30db },
00267 { XK_kana_MA, 0x30de },
00268 { XK_kana_MI, 0x30df },
00269 { XK_kana_MU, 0x30e0 },
00270 { XK_kana_ME, 0x30e1 },
00271 { XK_kana_MO, 0x30e2 },
00272 { XK_kana_YA, 0x30e4 },
00273 { XK_kana_YU, 0x30e6 },
00274 { XK_kana_YO, 0x30e8 },
00275 { XK_kana_RA, 0x30e9 },
00276 { XK_kana_RI, 0x30ea },
00277 { XK_kana_RU, 0x30eb },
00278 { XK_kana_RE, 0x30ec },
00279 { XK_kana_RO, 0x30ed },
00280 { XK_kana_WA, 0x30ef },
00281 { XK_kana_N, 0x30f3 },
00282 { XK_voicedsound, 0x309b },
00283 { XK_semivoicedsound, 0x309c },
00284 #endif // defined(XK_overline)
00285 #if defined(XK_Farsi_0)
00286 { XK_Farsi_0, 0x06f0 },
00287 { XK_Farsi_1, 0x06f1 },
00288 { XK_Farsi_2, 0x06f2 },
00289 { XK_Farsi_3, 0x06f3 },
00290 { XK_Farsi_4, 0x06f4 },
00291 { XK_Farsi_5, 0x06f5 },
00292 { XK_Farsi_6, 0x06f6 },
00293 { XK_Farsi_7, 0x06f7 },
00294 { XK_Farsi_8, 0x06f8 },
00295 { XK_Farsi_9, 0x06f9 },
00296 { XK_Arabic_percent, 0x066a },
00297 { XK_Arabic_superscript_alef, 0x0670 },
00298 { XK_Arabic_tteh, 0x0679 },
00299 { XK_Arabic_peh, 0x067e },
00300 { XK_Arabic_tcheh, 0x0686 },
00301 { XK_Arabic_ddal, 0x0688 },
00302 { XK_Arabic_rreh, 0x0691 },
00303 { XK_Arabic_comma, 0x060c },
00304 { XK_Arabic_fullstop, 0x06d4 },
00305 { XK_Arabic_semicolon, 0x061b },
00306 { XK_Arabic_0, 0x0660 },
00307 { XK_Arabic_1, 0x0661 },
00308 { XK_Arabic_2, 0x0662 },
00309 { XK_Arabic_3, 0x0663 },
00310 { XK_Arabic_4, 0x0664 },
00311 { XK_Arabic_5, 0x0665 },
00312 { XK_Arabic_6, 0x0666 },
00313 { XK_Arabic_7, 0x0667 },
00314 { XK_Arabic_8, 0x0668 },
00315 { XK_Arabic_9, 0x0669 },
00316 { XK_Arabic_question_mark, 0x061f },
00317 { XK_Arabic_hamza, 0x0621 },
00318 { XK_Arabic_maddaonalef, 0x0622 },
00319 { XK_Arabic_hamzaonalef, 0x0623 },
00320 { XK_Arabic_hamzaonwaw, 0x0624 },
00321 { XK_Arabic_hamzaunderalef, 0x0625 },
00322 { XK_Arabic_hamzaonyeh, 0x0626 },
00323 { XK_Arabic_alef, 0x0627 },
00324 { XK_Arabic_beh, 0x0628 },
00325 { XK_Arabic_tehmarbuta, 0x0629 },
00326 { XK_Arabic_teh, 0x062a },
00327 { XK_Arabic_theh, 0x062b },
00328 { XK_Arabic_jeem, 0x062c },
00329 { XK_Arabic_hah, 0x062d },
00330 { XK_Arabic_khah, 0x062e },
00331 { XK_Arabic_dal, 0x062f },
00332 { XK_Arabic_thal, 0x0630 },
00333 { XK_Arabic_ra, 0x0631 },
00334 { XK_Arabic_zain, 0x0632 },
00335 { XK_Arabic_seen, 0x0633 },
00336 { XK_Arabic_sheen, 0x0634 },
00337 { XK_Arabic_sad, 0x0635 },
00338 { XK_Arabic_dad, 0x0636 },
00339 { XK_Arabic_tah, 0x0637 },
00340 { XK_Arabic_zah, 0x0638 },
00341 { XK_Arabic_ain, 0x0639 },
00342 { XK_Arabic_ghain, 0x063a },
00343 { XK_Arabic_tatweel, 0x0640 },
00344 { XK_Arabic_feh, 0x0641 },
00345 { XK_Arabic_qaf, 0x0642 },
00346 { XK_Arabic_kaf, 0x0643 },
00347 { XK_Arabic_lam, 0x0644 },
00348 { XK_Arabic_meem, 0x0645 },
00349 { XK_Arabic_noon, 0x0646 },
00350 { XK_Arabic_ha, 0x0647 },
00351 { XK_Arabic_waw, 0x0648 },
00352 { XK_Arabic_alefmaksura, 0x0649 },
00353 { XK_Arabic_yeh, 0x064a },
00354 { XK_Arabic_fathatan, 0x064b },
00355 { XK_Arabic_dammatan, 0x064c },
00356 { XK_Arabic_kasratan, 0x064d },
00357 { XK_Arabic_fatha, 0x064e },
00358 { XK_Arabic_damma, 0x064f },
00359 { XK_Arabic_kasra, 0x0650 },
00360 { XK_Arabic_shadda, 0x0651 },
00361 { XK_Arabic_sukun, 0x0652 },
00362 { XK_Arabic_madda_above, 0x0653 },
00363 { XK_Arabic_hamza_above, 0x0654 },
00364 { XK_Arabic_hamza_below, 0x0655 },
00365 { XK_Arabic_jeh, 0x0698 },
00366 { XK_Arabic_veh, 0x06a4 },
00367 { XK_Arabic_keheh, 0x06a9 },
00368 { XK_Arabic_gaf, 0x06af },
00369 { XK_Arabic_noon_ghunna, 0x06ba },
00370 { XK_Arabic_heh_doachashmee, 0x06be },
00371 { XK_Arabic_farsi_yeh, 0x06cc },
00372 { XK_Arabic_yeh_baree, 0x06d2 },
00373 { XK_Arabic_heh_goal, 0x06c1 },
00374 #endif // defined(XK_Farsi_0)
00375 #if defined(XK_Serbian_dje)
00376 { XK_Serbian_dje, 0x0452 },
00377 { XK_Macedonia_gje, 0x0453 },
00378 { XK_Cyrillic_io, 0x0451 },
00379 { XK_Ukrainian_ie, 0x0454 },
00380 { XK_Macedonia_dse, 0x0455 },
00381 { XK_Ukrainian_i, 0x0456 },
00382 { XK_Ukrainian_yi, 0x0457 },
00383 { XK_Cyrillic_je, 0x0458 },
00384 { XK_Cyrillic_lje, 0x0459 },
00385 { XK_Cyrillic_nje, 0x045a },
00386 { XK_Serbian_tshe, 0x045b },
00387 { XK_Macedonia_kje, 0x045c },
00388 #if defined(XK_Ukrainian_ghe_with_upturn)
00389 { XK_Ukrainian_ghe_with_upturn, 0x0491 },
00390 #endif
00391 { XK_Byelorussian_shortu, 0x045e },
00392 { XK_Cyrillic_dzhe, 0x045f },
00393 { XK_numerosign, 0x2116 },
00394 { XK_Serbian_DJE, 0x0402 },
00395 { XK_Macedonia_GJE, 0x0403 },
00396 { XK_Cyrillic_IO, 0x0401 },
00397 { XK_Ukrainian_IE, 0x0404 },
00398 { XK_Macedonia_DSE, 0x0405 },
00399 { XK_Ukrainian_I, 0x0406 },
00400 { XK_Ukrainian_YI, 0x0407 },
00401 { XK_Cyrillic_JE, 0x0408 },
00402 { XK_Cyrillic_LJE, 0x0409 },
00403 { XK_Cyrillic_NJE, 0x040a },
00404 { XK_Serbian_TSHE, 0x040b },
00405 { XK_Macedonia_KJE, 0x040c },
00406 #if defined(XK_Ukrainian_GHE_WITH_UPTURN)
00407 { XK_Ukrainian_GHE_WITH_UPTURN, 0x0490 },
00408 #endif
00409 { XK_Byelorussian_SHORTU, 0x040e },
00410 { XK_Cyrillic_DZHE, 0x040f },
00411 { XK_Cyrillic_yu, 0x044e },
00412 { XK_Cyrillic_a, 0x0430 },
00413 { XK_Cyrillic_be, 0x0431 },
00414 { XK_Cyrillic_tse, 0x0446 },
00415 { XK_Cyrillic_de, 0x0434 },
00416 { XK_Cyrillic_ie, 0x0435 },
00417 { XK_Cyrillic_ef, 0x0444 },
00418 { XK_Cyrillic_ghe, 0x0433 },
00419 { XK_Cyrillic_ha, 0x0445 },
00420 { XK_Cyrillic_i, 0x0438 },
00421 { XK_Cyrillic_shorti, 0x0439 },
00422 { XK_Cyrillic_ka, 0x043a },
00423 { XK_Cyrillic_el, 0x043b },
00424 { XK_Cyrillic_em, 0x043c },
00425 { XK_Cyrillic_en, 0x043d },
00426 { XK_Cyrillic_o, 0x043e },
00427 { XK_Cyrillic_pe, 0x043f },
00428 { XK_Cyrillic_ya, 0x044f },
00429 { XK_Cyrillic_er, 0x0440 },
00430 { XK_Cyrillic_es, 0x0441 },
00431 { XK_Cyrillic_te, 0x0442 },
00432 { XK_Cyrillic_u, 0x0443 },
00433 { XK_Cyrillic_zhe, 0x0436 },
00434 { XK_Cyrillic_ve, 0x0432 },
00435 { XK_Cyrillic_softsign, 0x044c },
00436 { XK_Cyrillic_yeru, 0x044b },
00437 { XK_Cyrillic_ze, 0x0437 },
00438 { XK_Cyrillic_sha, 0x0448 },
00439 { XK_Cyrillic_e, 0x044d },
00440 { XK_Cyrillic_shcha, 0x0449 },
00441 { XK_Cyrillic_che, 0x0447 },
00442 { XK_Cyrillic_hardsign, 0x044a },
00443 { XK_Cyrillic_YU, 0x042e },
00444 { XK_Cyrillic_A, 0x0410 },
00445 { XK_Cyrillic_BE, 0x0411 },
00446 { XK_Cyrillic_TSE, 0x0426 },
00447 { XK_Cyrillic_DE, 0x0414 },
00448 { XK_Cyrillic_IE, 0x0415 },
00449 { XK_Cyrillic_EF, 0x0424 },
00450 { XK_Cyrillic_GHE, 0x0413 },
00451 { XK_Cyrillic_HA, 0x0425 },
00452 { XK_Cyrillic_I, 0x0418 },
00453 { XK_Cyrillic_SHORTI, 0x0419 },
00454 { XK_Cyrillic_KA, 0x041a },
00455 { XK_Cyrillic_EL, 0x041b },
00456 { XK_Cyrillic_EM, 0x041c },
00457 { XK_Cyrillic_EN, 0x041d },
00458 { XK_Cyrillic_O, 0x041e },
00459 { XK_Cyrillic_PE, 0x041f },
00460 { XK_Cyrillic_YA, 0x042f },
00461 { XK_Cyrillic_ER, 0x0420 },
00462 { XK_Cyrillic_ES, 0x0421 },
00463 { XK_Cyrillic_TE, 0x0422 },
00464 { XK_Cyrillic_U, 0x0423 },
00465 { XK_Cyrillic_ZHE, 0x0416 },
00466 { XK_Cyrillic_VE, 0x0412 },
00467 { XK_Cyrillic_SOFTSIGN, 0x042c },
00468 { XK_Cyrillic_YERU, 0x042b },
00469 { XK_Cyrillic_ZE, 0x0417 },
00470 { XK_Cyrillic_SHA, 0x0428 },
00471 { XK_Cyrillic_E, 0x042d },
00472 { XK_Cyrillic_SHCHA, 0x0429 },
00473 { XK_Cyrillic_CHE, 0x0427 },
00474 { XK_Cyrillic_HARDSIGN, 0x042a },
00475 #endif // defined(XK_Serbian_dje)
00476 #if defined(XK_Greek_ALPHAaccent)
00477 { XK_Greek_ALPHAaccent, 0x0386 },
00478 { XK_Greek_EPSILONaccent, 0x0388 },
00479 { XK_Greek_ETAaccent, 0x0389 },
00480 { XK_Greek_IOTAaccent, 0x038a },
00481 { XK_Greek_IOTAdiaeresis, 0x03aa },
00482 { XK_Greek_OMICRONaccent, 0x038c },
00483 { XK_Greek_UPSILONaccent, 0x038e },
00484 { XK_Greek_UPSILONdieresis, 0x03ab },
00485 { XK_Greek_OMEGAaccent, 0x038f },
00486 { XK_Greek_accentdieresis, 0x0385 },
00487 { XK_Greek_horizbar, 0x2015 },
00488 { XK_Greek_alphaaccent, 0x03ac },
00489 { XK_Greek_epsilonaccent, 0x03ad },
00490 { XK_Greek_etaaccent, 0x03ae },
00491 { XK_Greek_iotaaccent, 0x03af },
00492 { XK_Greek_iotadieresis, 0x03ca },
00493 { XK_Greek_iotaaccentdieresis, 0x0390 },
00494 { XK_Greek_omicronaccent, 0x03cc },
00495 { XK_Greek_upsilonaccent, 0x03cd },
00496 { XK_Greek_upsilondieresis, 0x03cb },
00497 { XK_Greek_upsilonaccentdieresis, 0x03b0 },
00498 { XK_Greek_omegaaccent, 0x03ce },
00499 { XK_Greek_ALPHA, 0x0391 },
00500 { XK_Greek_BETA, 0x0392 },
00501 { XK_Greek_GAMMA, 0x0393 },
00502 { XK_Greek_DELTA, 0x0394 },
00503 { XK_Greek_EPSILON, 0x0395 },
00504 { XK_Greek_ZETA, 0x0396 },
00505 { XK_Greek_ETA, 0x0397 },
00506 { XK_Greek_THETA, 0x0398 },
00507 { XK_Greek_IOTA, 0x0399 },
00508 { XK_Greek_KAPPA, 0x039a },
00509 { XK_Greek_LAMBDA, 0x039b },
00510 { XK_Greek_MU, 0x039c },
00511 { XK_Greek_NU, 0x039d },
00512 { XK_Greek_XI, 0x039e },
00513 { XK_Greek_OMICRON, 0x039f },
00514 { XK_Greek_PI, 0x03a0 },
00515 { XK_Greek_RHO, 0x03a1 },
00516 { XK_Greek_SIGMA, 0x03a3 },
00517 { XK_Greek_TAU, 0x03a4 },
00518 { XK_Greek_UPSILON, 0x03a5 },
00519 { XK_Greek_PHI, 0x03a6 },
00520 { XK_Greek_CHI, 0x03a7 },
00521 { XK_Greek_PSI, 0x03a8 },
00522 { XK_Greek_OMEGA, 0x03a9 },
00523 { XK_Greek_alpha, 0x03b1 },
00524 { XK_Greek_beta, 0x03b2 },
00525 { XK_Greek_gamma, 0x03b3 },
00526 { XK_Greek_delta, 0x03b4 },
00527 { XK_Greek_epsilon, 0x03b5 },
00528 { XK_Greek_zeta, 0x03b6 },
00529 { XK_Greek_eta, 0x03b7 },
00530 { XK_Greek_theta, 0x03b8 },
00531 { XK_Greek_iota, 0x03b9 },
00532 { XK_Greek_kappa, 0x03ba },
00533 { XK_Greek_lambda, 0x03bb },
00534 { XK_Greek_mu, 0x03bc },
00535 { XK_Greek_nu, 0x03bd },
00536 { XK_Greek_xi, 0x03be },
00537 { XK_Greek_omicron, 0x03bf },
00538 { XK_Greek_pi, 0x03c0 },
00539 { XK_Greek_rho, 0x03c1 },
00540 { XK_Greek_sigma, 0x03c3 },
00541 { XK_Greek_finalsmallsigma, 0x03c2 },
00542 { XK_Greek_tau, 0x03c4 },
00543 { XK_Greek_upsilon, 0x03c5 },
00544 { XK_Greek_phi, 0x03c6 },
00545 { XK_Greek_chi, 0x03c7 },
00546 { XK_Greek_psi, 0x03c8 },
00547 { XK_Greek_omega, 0x03c9 },
00548 #endif // defined(XK_Greek_ALPHAaccent)
00549 { XK_leftradical, 0x23b7 },
00550 { XK_topleftradical, 0x250c },
00551 { XK_horizconnector, 0x2500 },
00552 { XK_topintegral, 0x2320 },
00553 { XK_botintegral, 0x2321 },
00554 { XK_vertconnector, 0x2502 },
00555 { XK_topleftsqbracket, 0x23a1 },
00556 { XK_botleftsqbracket, 0x23a3 },
00557 { XK_toprightsqbracket, 0x23a4 },
00558 { XK_botrightsqbracket, 0x23a6 },
00559 { XK_topleftparens, 0x239b },
00560 { XK_botleftparens, 0x239d },
00561 { XK_toprightparens, 0x239e },
00562 { XK_botrightparens, 0x23a0 },
00563 { XK_leftmiddlecurlybrace, 0x23a8 },
00564 { XK_rightmiddlecurlybrace, 0x23ac },
00565 { XK_lessthanequal, 0x2264 },
00566 { XK_notequal, 0x2260 },
00567 { XK_greaterthanequal, 0x2265 },
00568 { XK_integral, 0x222b },
00569 { XK_therefore, 0x2234 },
00570 { XK_variation, 0x221d },
00571 { XK_infinity, 0x221e },
00572 { XK_nabla, 0x2207 },
00573 { XK_approximate, 0x223c },
00574 { XK_similarequal, 0x2243 },
00575 { XK_ifonlyif, 0x21d4 },
00576 { XK_implies, 0x21d2 },
00577 { XK_identical, 0x2261 },
00578 { XK_radical, 0x221a },
00579 { XK_includedin, 0x2282 },
00580 { XK_includes, 0x2283 },
00581 { XK_intersection, 0x2229 },
00582 { XK_union, 0x222a },
00583 { XK_logicaland, 0x2227 },
00584 { XK_logicalor, 0x2228 },
00585 { XK_partialderivative, 0x2202 },
00586 { XK_function, 0x0192 },
00587 { XK_leftarrow, 0x2190 },
00588 { XK_uparrow, 0x2191 },
00589 { XK_rightarrow, 0x2192 },
00590 { XK_downarrow, 0x2193 },
00591
00592 { XK_soliddiamond, 0x25c6 },
00593 { XK_checkerboard, 0x2592 },
00594 { XK_ht, 0x2409 },
00595 { XK_ff, 0x240c },
00596 { XK_cr, 0x240d },
00597 { XK_lf, 0x240a },
00598 { XK_nl, 0x2424 },
00599 { XK_vt, 0x240b },
00600 { XK_lowrightcorner, 0x2518 },
00601 { XK_uprightcorner, 0x2510 },
00602 { XK_upleftcorner, 0x250c },
00603 { XK_lowleftcorner, 0x2514 },
00604 { XK_crossinglines, 0x253c },
00605 { XK_horizlinescan1, 0x23ba },
00606 { XK_horizlinescan3, 0x23bb },
00607 { XK_horizlinescan5, 0x2500 },
00608 { XK_horizlinescan7, 0x23bc },
00609 { XK_horizlinescan9, 0x23bd },
00610 { XK_leftt, 0x251c },
00611 { XK_rightt, 0x2524 },
00612 { XK_bott, 0x2534 },
00613 { XK_topt, 0x252c },
00614 { XK_vertbar, 0x2502 },
00615 { XK_emspace, 0x2003 },
00616 { XK_enspace, 0x2002 },
00617 { XK_em3space, 0x2004 },
00618 { XK_em4space, 0x2005 },
00619 { XK_digitspace, 0x2007 },
00620 { XK_punctspace, 0x2008 },
00621 { XK_thinspace, 0x2009 },
00622 { XK_hairspace, 0x200a },
00623 { XK_emdash, 0x2014 },
00624 { XK_endash, 0x2013 },
00625
00626 { XK_ellipsis, 0x2026 },
00627 { XK_doubbaselinedot, 0x2025 },
00628 { XK_onethird, 0x2153 },
00629 { XK_twothirds, 0x2154 },
00630 { XK_onefifth, 0x2155 },
00631 { XK_twofifths, 0x2156 },
00632 { XK_threefifths, 0x2157 },
00633 { XK_fourfifths, 0x2158 },
00634 { XK_onesixth, 0x2159 },
00635 { XK_fivesixths, 0x215a },
00636 { XK_careof, 0x2105 },
00637 { XK_figdash, 0x2012 },
00638 { XK_leftanglebracket, 0x2329 },
00639
00640 { XK_rightanglebracket, 0x232a },
00641
00642 { XK_oneeighth, 0x215b },
00643 { XK_threeeighths, 0x215c },
00644 { XK_fiveeighths, 0x215d },
00645 { XK_seveneighths, 0x215e },
00646 { XK_trademark, 0x2122 },
00647 { XK_signaturemark, 0x2613 },
00648
00649 { XK_leftopentriangle, 0x25c1 },
00650 { XK_rightopentriangle, 0x25b7 },
00651 { XK_emopencircle, 0x25cb },
00652 { XK_emopenrectangle, 0x25af },
00653 { XK_leftsinglequotemark, 0x2018 },
00654 { XK_rightsinglequotemark, 0x2019 },
00655 { XK_leftdoublequotemark, 0x201c },
00656 { XK_rightdoublequotemark, 0x201d },
00657 { XK_prescription, 0x211e },
00658 { XK_minutes, 0x2032 },
00659 { XK_seconds, 0x2033 },
00660 { XK_latincross, 0x271d },
00661
00662 { XK_filledrectbullet, 0x25ac },
00663 { XK_filledlefttribullet, 0x25c0 },
00664 { XK_filledrighttribullet, 0x25b6 },
00665 { XK_emfilledcircle, 0x25cf },
00666 { XK_emfilledrect, 0x25ae },
00667 { XK_enopencircbullet, 0x25e6 },
00668 { XK_enopensquarebullet, 0x25ab },
00669 { XK_openrectbullet, 0x25ad },
00670 { XK_opentribulletup, 0x25b3 },
00671 { XK_opentribulletdown, 0x25bd },
00672 { XK_openstar, 0x2606 },
00673 { XK_enfilledcircbullet, 0x2022 },
00674 { XK_enfilledsqbullet, 0x25aa },
00675 { XK_filledtribulletup, 0x25b2 },
00676 { XK_filledtribulletdown, 0x25bc },
00677 { XK_leftpointer, 0x261c },
00678 { XK_rightpointer, 0x261e },
00679 { XK_club, 0x2663 },
00680 { XK_diamond, 0x2666 },
00681 { XK_heart, 0x2665 },
00682 { XK_maltesecross, 0x2720 },
00683 { XK_dagger, 0x2020 },
00684 { XK_doubledagger, 0x2021 },
00685 { XK_checkmark, 0x2713 },
00686 { XK_ballotcross, 0x2717 },
00687 { XK_musicalsharp, 0x266f },
00688 { XK_musicalflat, 0x266d },
00689 { XK_malesymbol, 0x2642 },
00690 { XK_femalesymbol, 0x2640 },
00691 { XK_telephone, 0x260e },
00692 { XK_telephonerecorder, 0x2315 },
00693 { XK_phonographcopyright, 0x2117 },
00694 { XK_caret, 0x2038 },
00695 { XK_singlelowquotemark, 0x201a },
00696 { XK_doublelowquotemark, 0x201e },
00697
00698 { XK_leftcaret, 0x003c },
00699 { XK_rightcaret, 0x003e },
00700 { XK_downcaret, 0x2228 },
00701 { XK_upcaret, 0x2227 },
00702 { XK_overbar, 0x00af },
00703 { XK_downtack, 0x22a5 },
00704 { XK_upshoe, 0x2229 },
00705 { XK_downstile, 0x230a },
00706 { XK_underbar, 0x005f },
00707 { XK_jot, 0x2218 },
00708 { XK_quad, 0x2395 },
00709 { XK_uptack, 0x22a4 },
00710 { XK_circle, 0x25cb },
00711 { XK_upstile, 0x2308 },
00712 { XK_downshoe, 0x222a },
00713 { XK_rightshoe, 0x2283 },
00714 { XK_leftshoe, 0x2282 },
00715 { XK_lefttack, 0x22a2 },
00716 { XK_righttack, 0x22a3 },
00717 #if defined(XK_hebrew_doublelowline)
00718 { XK_hebrew_doublelowline, 0x2017 },
00719 { XK_hebrew_aleph, 0x05d0 },
00720 { XK_hebrew_bet, 0x05d1 },
00721 { XK_hebrew_gimel, 0x05d2 },
00722 { XK_hebrew_dalet, 0x05d3 },
00723 { XK_hebrew_he, 0x05d4 },
00724 { XK_hebrew_waw, 0x05d5 },
00725 { XK_hebrew_zain, 0x05d6 },
00726 { XK_hebrew_chet, 0x05d7 },
00727 { XK_hebrew_tet, 0x05d8 },
00728 { XK_hebrew_yod, 0x05d9 },
00729 { XK_hebrew_finalkaph, 0x05da },
00730 { XK_hebrew_kaph, 0x05db },
00731 { XK_hebrew_lamed, 0x05dc },
00732 { XK_hebrew_finalmem, 0x05dd },
00733 { XK_hebrew_mem, 0x05de },
00734 { XK_hebrew_finalnun, 0x05df },
00735 { XK_hebrew_nun, 0x05e0 },
00736 { XK_hebrew_samech, 0x05e1 },
00737 { XK_hebrew_ayin, 0x05e2 },
00738 { XK_hebrew_finalpe, 0x05e3 },
00739 { XK_hebrew_pe, 0x05e4 },
00740 { XK_hebrew_finalzade, 0x05e5 },
00741 { XK_hebrew_zade, 0x05e6 },
00742 { XK_hebrew_qoph, 0x05e7 },
00743 { XK_hebrew_resh, 0x05e8 },
00744 { XK_hebrew_shin, 0x05e9 },
00745 { XK_hebrew_taw, 0x05ea },
00746 #endif // defined(XK_hebrew_doublelowline)
00747 #if defined(XK_Thai_kokai)
00748 { XK_Thai_kokai, 0x0e01 },
00749 { XK_Thai_khokhai, 0x0e02 },
00750 { XK_Thai_khokhuat, 0x0e03 },
00751 { XK_Thai_khokhwai, 0x0e04 },
00752 { XK_Thai_khokhon, 0x0e05 },
00753 { XK_Thai_khorakhang, 0x0e06 },
00754 { XK_Thai_ngongu, 0x0e07 },
00755 { XK_Thai_chochan, 0x0e08 },
00756 { XK_Thai_choching, 0x0e09 },
00757 { XK_Thai_chochang, 0x0e0a },
00758 { XK_Thai_soso, 0x0e0b },
00759 { XK_Thai_chochoe, 0x0e0c },
00760 { XK_Thai_yoying, 0x0e0d },
00761 { XK_Thai_dochada, 0x0e0e },
00762 { XK_Thai_topatak, 0x0e0f },
00763 { XK_Thai_thothan, 0x0e10 },
00764 { XK_Thai_thonangmontho, 0x0e11 },
00765 { XK_Thai_thophuthao, 0x0e12 },
00766 { XK_Thai_nonen, 0x0e13 },
00767 { XK_Thai_dodek, 0x0e14 },
00768 { XK_Thai_totao, 0x0e15 },
00769 { XK_Thai_thothung, 0x0e16 },
00770 { XK_Thai_thothahan, 0x0e17 },
00771 { XK_Thai_thothong, 0x0e18 },
00772 { XK_Thai_nonu, 0x0e19 },
00773 { XK_Thai_bobaimai, 0x0e1a },
00774 { XK_Thai_popla, 0x0e1b },
00775 { XK_Thai_phophung, 0x0e1c },
00776 { XK_Thai_fofa, 0x0e1d },
00777 { XK_Thai_phophan, 0x0e1e },
00778 { XK_Thai_fofan, 0x0e1f },
00779 { XK_Thai_phosamphao, 0x0e20 },
00780 { XK_Thai_moma, 0x0e21 },
00781 { XK_Thai_yoyak, 0x0e22 },
00782 { XK_Thai_rorua, 0x0e23 },
00783 { XK_Thai_ru, 0x0e24 },
00784 { XK_Thai_loling, 0x0e25 },
00785 { XK_Thai_lu, 0x0e26 },
00786 { XK_Thai_wowaen, 0x0e27 },
00787 { XK_Thai_sosala, 0x0e28 },
00788 { XK_Thai_sorusi, 0x0e29 },
00789 { XK_Thai_sosua, 0x0e2a },
00790 { XK_Thai_hohip, 0x0e2b },
00791 { XK_Thai_lochula, 0x0e2c },
00792 { XK_Thai_oang, 0x0e2d },
00793 { XK_Thai_honokhuk, 0x0e2e },
00794 { XK_Thai_paiyannoi, 0x0e2f },
00795 { XK_Thai_saraa, 0x0e30 },
00796 { XK_Thai_maihanakat, 0x0e31 },
00797 { XK_Thai_saraaa, 0x0e32 },
00798 { XK_Thai_saraam, 0x0e33 },
00799 { XK_Thai_sarai, 0x0e34 },
00800 { XK_Thai_saraii, 0x0e35 },
00801 { XK_Thai_saraue, 0x0e36 },
00802 { XK_Thai_sarauee, 0x0e37 },
00803 { XK_Thai_sarau, 0x0e38 },
00804 { XK_Thai_sarauu, 0x0e39 },
00805 { XK_Thai_phinthu, 0x0e3a },
00806
00807 { XK_Thai_baht, 0x0e3f },
00808 { XK_Thai_sarae, 0x0e40 },
00809 { XK_Thai_saraae, 0x0e41 },
00810 { XK_Thai_sarao, 0x0e42 },
00811 { XK_Thai_saraaimaimuan, 0x0e43 },
00812 { XK_Thai_saraaimaimalai, 0x0e44 },
00813 { XK_Thai_lakkhangyao, 0x0e45 },
00814 { XK_Thai_maiyamok, 0x0e46 },
00815 { XK_Thai_maitaikhu, 0x0e47 },
00816 { XK_Thai_maiek, 0x0e48 },
00817 { XK_Thai_maitho, 0x0e49 },
00818 { XK_Thai_maitri, 0x0e4a },
00819 { XK_Thai_maichattawa, 0x0e4b },
00820 { XK_Thai_thanthakhat, 0x0e4c },
00821 { XK_Thai_nikhahit, 0x0e4d },
00822 { XK_Thai_leksun, 0x0e50 },
00823 { XK_Thai_leknung, 0x0e51 },
00824 { XK_Thai_leksong, 0x0e52 },
00825 { XK_Thai_leksam, 0x0e53 },
00826 { XK_Thai_leksi, 0x0e54 },
00827 { XK_Thai_lekha, 0x0e55 },
00828 { XK_Thai_lekhok, 0x0e56 },
00829 { XK_Thai_lekchet, 0x0e57 },
00830 { XK_Thai_lekpaet, 0x0e58 },
00831 { XK_Thai_lekkao, 0x0e59 },
00832 #endif // defined(XK_Thai_kokai)
00833 #if defined(XK_Hangul_Kiyeog)
00834 { XK_Hangul_Kiyeog, 0x3131 },
00835 { XK_Hangul_SsangKiyeog, 0x3132 },
00836 { XK_Hangul_KiyeogSios, 0x3133 },
00837 { XK_Hangul_Nieun, 0x3134 },
00838 { XK_Hangul_NieunJieuj, 0x3135 },
00839 { XK_Hangul_NieunHieuh, 0x3136 },
00840 { XK_Hangul_Dikeud, 0x3137 },
00841 { XK_Hangul_SsangDikeud, 0x3138 },
00842 { XK_Hangul_Rieul, 0x3139 },
00843 { XK_Hangul_RieulKiyeog, 0x313a },
00844 { XK_Hangul_RieulMieum, 0x313b },
00845 { XK_Hangul_RieulPieub, 0x313c },
00846 { XK_Hangul_RieulSios, 0x313d },
00847 { XK_Hangul_RieulTieut, 0x313e },
00848 { XK_Hangul_RieulPhieuf, 0x313f },
00849 { XK_Hangul_RieulHieuh, 0x3140 },
00850 { XK_Hangul_Mieum, 0x3141 },
00851 { XK_Hangul_Pieub, 0x3142 },
00852 { XK_Hangul_SsangPieub, 0x3143 },
00853 { XK_Hangul_PieubSios, 0x3144 },
00854 { XK_Hangul_Sios, 0x3145 },
00855 { XK_Hangul_SsangSios, 0x3146 },
00856 { XK_Hangul_Ieung, 0x3147 },
00857 { XK_Hangul_Jieuj, 0x3148 },
00858 { XK_Hangul_SsangJieuj, 0x3149 },
00859 { XK_Hangul_Cieuc, 0x314a },
00860 { XK_Hangul_Khieuq, 0x314b },
00861 { XK_Hangul_Tieut, 0x314c },
00862 { XK_Hangul_Phieuf, 0x314d },
00863 { XK_Hangul_Hieuh, 0x314e },
00864 { XK_Hangul_A, 0x314f },
00865 { XK_Hangul_AE, 0x3150 },
00866 { XK_Hangul_YA, 0x3151 },
00867 { XK_Hangul_YAE, 0x3152 },
00868 { XK_Hangul_EO, 0x3153 },
00869 { XK_Hangul_E, 0x3154 },
00870 { XK_Hangul_YEO, 0x3155 },
00871 { XK_Hangul_YE, 0x3156 },
00872 { XK_Hangul_O, 0x3157 },
00873 { XK_Hangul_WA, 0x3158 },
00874 { XK_Hangul_WAE, 0x3159 },
00875 { XK_Hangul_OE, 0x315a },
00876 { XK_Hangul_YO, 0x315b },
00877 { XK_Hangul_U, 0x315c },
00878 { XK_Hangul_WEO, 0x315d },
00879 { XK_Hangul_WE, 0x315e },
00880 { XK_Hangul_WI, 0x315f },
00881 { XK_Hangul_YU, 0x3160 },
00882 { XK_Hangul_EU, 0x3161 },
00883 { XK_Hangul_YI, 0x3162 },
00884 { XK_Hangul_I, 0x3163 },
00885 { XK_Hangul_J_Kiyeog, 0x11a8 },
00886 { XK_Hangul_J_SsangKiyeog, 0x11a9 },
00887 { XK_Hangul_J_KiyeogSios, 0x11aa },
00888 { XK_Hangul_J_Nieun, 0x11ab },
00889 { XK_Hangul_J_NieunJieuj, 0x11ac },
00890 { XK_Hangul_J_NieunHieuh, 0x11ad },
00891 { XK_Hangul_J_Dikeud, 0x11ae },
00892 { XK_Hangul_J_Rieul, 0x11af },
00893 { XK_Hangul_J_RieulKiyeog, 0x11b0 },
00894 { XK_Hangul_J_RieulMieum, 0x11b1 },
00895 { XK_Hangul_J_RieulPieub, 0x11b2 },
00896 { XK_Hangul_J_RieulSios, 0x11b3 },
00897 { XK_Hangul_J_RieulTieut, 0x11b4 },
00898 { XK_Hangul_J_RieulPhieuf, 0x11b5 },
00899 { XK_Hangul_J_RieulHieuh, 0x11b6 },
00900 { XK_Hangul_J_Mieum, 0x11b7 },
00901 { XK_Hangul_J_Pieub, 0x11b8 },
00902 { XK_Hangul_J_PieubSios, 0x11b9 },
00903 { XK_Hangul_J_Sios, 0x11ba },
00904 { XK_Hangul_J_SsangSios, 0x11bb },
00905 { XK_Hangul_J_Ieung, 0x11bc },
00906 { XK_Hangul_J_Jieuj, 0x11bd },
00907 { XK_Hangul_J_Cieuc, 0x11be },
00908 { XK_Hangul_J_Khieuq, 0x11bf },
00909 { XK_Hangul_J_Tieut, 0x11c0 },
00910 { XK_Hangul_J_Phieuf, 0x11c1 },
00911 { XK_Hangul_J_Hieuh, 0x11c2 },
00912 { XK_Hangul_RieulYeorinHieuh, 0x316d },
00913 { XK_Hangul_SunkyeongeumMieum, 0x3171 },
00914 { XK_Hangul_SunkyeongeumPieub, 0x3178 },
00915 { XK_Hangul_PanSios, 0x317f },
00916 { XK_Hangul_KkogjiDalrinIeung, 0x3181 },
00917 { XK_Hangul_SunkyeongeumPhieuf, 0x3184 },
00918 { XK_Hangul_YeorinHieuh, 0x3186 },
00919 { XK_Hangul_AraeA, 0x318d },
00920 { XK_Hangul_AraeAE, 0x318e },
00921 { XK_Hangul_J_PanSios, 0x11eb },
00922 { XK_Hangul_J_KkogjiDalrinIeung, 0x11f0 },
00923 { XK_Hangul_J_YeorinHieuh, 0x11f9 },
00924 { XK_Korean_Won, 0x20a9 },
00925 #endif // defined(XK_Hangul_Kiyeog)
00926 { XK_OE, 0x0152 },
00927 { XK_oe, 0x0153 },
00928 { XK_Ydiaeresis, 0x0178 },
00929 { XK_EuroSign, 0x20ac },
00930
00931
00932 { XK_dead_abovedot, 0x0307 },
00933 { XK_dead_abovering, 0x030a },
00934 { XK_dead_acute, 0x0301 },
00935 { XK_dead_breve, 0x0306 },
00936 { XK_dead_caron, 0x030c },
00937 { XK_dead_cedilla, 0x0327 },
00938 { XK_dead_circumflex, 0x0302 },
00939 { XK_dead_diaeresis, 0x0308 },
00940 { XK_dead_doubleacute, 0x030b },
00941 { XK_dead_grave, 0x0300 },
00942 { XK_dead_macron, 0x0304 },
00943 { XK_dead_ogonek, 0x0328 },
00944 { XK_dead_tilde, 0x0303 }
00945 };
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 static const KeySym s_map1008FF[] =
01246 {
01247 0, 0, 0, 0, 0, 0, 0, 0,
01248 0, 0, 0, 0, 0, 0, 0, 0,
01249 0, kKeyAudioDown, kKeyAudioMute, kKeyAudioUp,
01250 kKeyAudioPlay, kKeyAudioStop, kKeyAudioPrev, kKeyAudioNext,
01251 kKeyWWWHome, kKeyAppMail, 0, kKeyWWWSearch, 0, 0, 0, 0,
01252 0, 0, 0, 0, 0, 0, kKeyWWWBack, kKeyWWWForward,
01253 kKeyWWWStop, kKeyWWWRefresh, 0, 0, kKeyEject, 0, 0, 0,
01254 kKeyWWWFavorites, 0, kKeyAppMedia, 0, 0, 0, 0, 0,
01255 0, 0, 0, 0, 0, 0, 0, 0,
01256 kKeyAppUser1, kKeyAppUser2, 0, 0, 0, 0, 0, 0,
01257 0, 0, 0, 0, 0, 0, 0, 0,
01258 0, 0, 0, 0, 0, 0, 0, 0,
01259 0, 0, 0, 0, 0, 0, 0, 0,
01260 0, 0, 0, 0, 0, 0, 0, 0,
01261 0, 0, 0, 0, 0, 0, 0, 0,
01262 0, 0, 0, 0, 0, 0, 0, 0,
01263 0, 0, 0, 0, 0, 0, 0, 0,
01264 0, 0, 0, 0, 0, 0, 0, 0,
01265 0, 0, 0, 0, 0, 0, 0, 0,
01266 0, 0, 0, 0, 0, 0, 0, 0,
01267 0, 0, 0, 0, 0, 0, 0, 0,
01268 0, 0, 0, 0, 0, 0, 0, 0,
01269 0, 0, 0, 0, 0, 0, 0, 0,
01270 0, 0, 0, 0, 0, 0, 0, 0,
01271 0, 0, 0, 0, 0, 0, 0, 0,
01272 0, 0, 0, 0, 0, 0, 0, 0,
01273 0, 0, 0, 0, 0, 0, 0, 0,
01274 0, 0, 0, 0, 0, 0, 0, 0,
01275 0, 0, 0, 0, 0, 0, 0, 0,
01276 0, 0, 0, 0, 0, 0, 0, 0,
01277 0, 0, 0, 0, 0, 0, 0, 0,
01278 0, 0, 0, 0, 0, 0, 0, 0,
01279 0, 0, 0, 0, 0, 0, 0, 0
01280 };
01281
01282
01283
01284
01285
01286
01287 CXWindowsUtil::CKeySymMap CXWindowsUtil::s_keySymToUCS4;
01288
01289 bool
01290 CXWindowsUtil::getWindowProperty(Display* display, Window window,
01291 Atom property, CString* data, Atom* type,
01292 SInt32* format, bool deleteProperty)
01293 {
01294 assert(display != NULL);
01295
01296 Atom actualType;
01297 int actualDatumSize;
01298
01299
01300 CXWindowsUtil::CErrorLock lock(display);
01301
01302
01303 bool okay = true;
01304 const long length = XMaxRequestSize(display);
01305 long offset = 0;
01306 unsigned long bytesLeft = 1;
01307 while (bytesLeft != 0) {
01308
01309 unsigned long numItems;
01310 unsigned char* rawData;
01311 if (XGetWindowProperty(display, window, property,
01312 offset, length, False, AnyPropertyType,
01313 &actualType, &actualDatumSize,
01314 &numItems, &bytesLeft, &rawData) != Success ||
01315 actualType == None || actualDatumSize == 0) {
01316
01317 okay = false;
01318 break;
01319 }
01320
01321
01322 unsigned long numBytes;
01323 switch (actualDatumSize) {
01324 case 8:
01325 default:
01326 numBytes = numItems;
01327 offset += numItems / 4;
01328 break;
01329
01330 case 16:
01331 numBytes = 2 * numItems;
01332 offset += numItems / 2;
01333 break;
01334
01335 case 32:
01336 numBytes = 4 * numItems;
01337 offset += numItems;
01338 break;
01339 }
01340
01341
01342 if (data != NULL) {
01343 data->append((char*)rawData, numBytes);
01344 }
01345 else {
01346
01347 bytesLeft = 0;
01348 }
01349
01350
01351 XFree(rawData);
01352 }
01353
01354
01355 if (deleteProperty) {
01356 XDeleteProperty(display, window, property);
01357 }
01358
01359
01360 if (type != NULL) {
01361 *type = actualType;
01362 }
01363 if (format != NULL) {
01364 *format = static_cast<SInt32>(actualDatumSize);
01365 }
01366
01367 if (okay) {
01368 LOG((CLOG_DEBUG2 "read property %d on window 0x%08x: bytes=%d", property, window, (data == NULL) ? 0 : data->size()));
01369 return true;
01370 }
01371 else {
01372 LOG((CLOG_DEBUG2 "can't read property %d on window 0x%08x", property, window));
01373 return false;
01374 }
01375 }
01376
01377 bool
01378 CXWindowsUtil::setWindowProperty(Display* display, Window window,
01379 Atom property, const void* vdata, UInt32 size,
01380 Atom type, SInt32 format)
01381 {
01382 const UInt32 length = 4 * XMaxRequestSize(display);
01383 const unsigned char* data = reinterpret_cast<const unsigned char*>(vdata);
01384 UInt32 datumSize = static_cast<UInt32>(format / 8);
01385
01386 if (format == 32) {
01387 datumSize = sizeof(Atom);
01388 }
01389
01390
01391 bool error = false;
01392 CXWindowsUtil::CErrorLock lock(display, &error);
01393
01394
01395 UInt32 chunkSize = size;
01396 if (chunkSize > length) {
01397 chunkSize = length;
01398 }
01399
01400
01401 XChangeProperty(display, window, property,
01402 type, format, PropModeReplace,
01403 data, chunkSize / datumSize);
01404
01405
01406 data += chunkSize;
01407 size -= chunkSize;
01408 while (!error && size > 0) {
01409 chunkSize = size;
01410 if (chunkSize > length) {
01411 chunkSize = length;
01412 }
01413 XChangeProperty(display, window, property,
01414 type, format, PropModeAppend,
01415 data, chunkSize / datumSize);
01416 data += chunkSize;
01417 size -= chunkSize;
01418 }
01419
01420 return !error;
01421 }
01422
01423 Time
01424 CXWindowsUtil::getCurrentTime(Display* display, Window window)
01425 {
01426
01427 XWindowAttributes attr;
01428 XGetWindowAttributes(display, window, &attr);
01429 XSelectInput(display, window, attr.your_event_mask | PropertyChangeMask);
01430
01431
01432 Atom atom = XInternAtom(display, "TIMESTAMP", False);
01433
01434
01435 unsigned char dummy;
01436 XChangeProperty(display, window, atom,
01437 XA_INTEGER, 8,
01438 PropModeAppend,
01439 &dummy, 0);
01440
01441
01442 CPropertyNotifyPredicateInfo filter;
01443 filter.m_window = window;
01444 filter.m_property = atom;
01445
01446
01447 XEvent xevent;
01448 XIfEvent(display, &xevent, &CXWindowsUtil::propertyNotifyPredicate,
01449 (XPointer)&filter);
01450 assert(xevent.type == PropertyNotify);
01451 assert(xevent.xproperty.window == window);
01452 assert(xevent.xproperty.atom == atom);
01453
01454
01455 XSelectInput(display, window, attr.your_event_mask);
01456
01457 return xevent.xproperty.time;
01458 }
01459
01460 KeyID
01461 CXWindowsUtil::mapKeySymToKeyID(KeySym k)
01462 {
01463 initKeyMaps();
01464
01465 switch (k & 0xffffff00) {
01466 case 0x0000:
01467
01468 return static_cast<KeyID>(k);
01469
01470 case 0xfe00:
01471
01472 switch (k) {
01473 case XK_ISO_Left_Tab:
01474 return kKeyLeftTab;
01475
01476 case XK_ISO_Level3_Shift:
01477 return kKeyAltGr;
01478
01479 case XK_ISO_Next_Group:
01480 return kKeyNextGroup;
01481
01482 case XK_ISO_Prev_Group:
01483 return kKeyPrevGroup;
01484
01485 case XK_dead_grave:
01486 return kKeyDeadGrave;
01487
01488 case XK_dead_acute:
01489 return kKeyDeadAcute;
01490
01491 case XK_dead_circumflex:
01492 return kKeyDeadCircumflex;
01493
01494 case XK_dead_tilde:
01495 return kKeyDeadTilde;
01496
01497 case XK_dead_macron:
01498 return kKeyDeadMacron;
01499
01500 case XK_dead_breve:
01501 return kKeyDeadBreve;
01502
01503 case XK_dead_abovedot:
01504 return kKeyDeadAbovedot;
01505
01506 case XK_dead_diaeresis:
01507 return kKeyDeadDiaeresis;
01508
01509 case XK_dead_abovering:
01510 return kKeyDeadAbovering;
01511
01512 case XK_dead_doubleacute:
01513 return kKeyDeadDoubleacute;
01514
01515 case XK_dead_caron:
01516 return kKeyDeadCaron;
01517
01518 case XK_dead_cedilla:
01519 return kKeyDeadCedilla;
01520
01521 case XK_dead_ogonek:
01522 return kKeyDeadOgonek;
01523
01524 default:
01525 return kKeyNone;
01526 }
01527
01528 case 0xff00:
01529
01530 return static_cast<KeyID>(k - 0xff00 + 0xef00);
01531
01532 case 0x1008ff00:
01533
01534 return s_map1008FF[k & 0xff];
01535
01536 default: {
01537
01538 CKeySymMap::const_iterator index = s_keySymToUCS4.find(k);
01539 if (index != s_keySymToUCS4.end()) {
01540 return static_cast<KeyID>(index->second);
01541 }
01542
01543
01544 return kKeyNone;
01545 }
01546 }
01547 }
01548
01549 UInt32
01550 CXWindowsUtil::getModifierBitForKeySym(KeySym keysym)
01551 {
01552 switch (keysym) {
01553 case XK_Shift_L:
01554 case XK_Shift_R:
01555 return kKeyModifierBitShift;
01556
01557 case XK_Control_L:
01558 case XK_Control_R:
01559 return kKeyModifierBitControl;
01560
01561 case XK_Alt_L:
01562 case XK_Alt_R:
01563 return kKeyModifierBitAlt;
01564
01565 case XK_Meta_L:
01566 case XK_Meta_R:
01567 return kKeyModifierBitMeta;
01568
01569 case XK_Super_L:
01570 case XK_Super_R:
01571 case XK_Hyper_L:
01572 case XK_Hyper_R:
01573 return kKeyModifierBitSuper;
01574
01575 case XK_Mode_switch:
01576 case XK_ISO_Level3_Shift:
01577 return kKeyModifierBitAltGr;
01578
01579 case XK_Caps_Lock:
01580 return kKeyModifierBitCapsLock;
01581
01582 case XK_Num_Lock:
01583 return kKeyModifierBitNumLock;
01584
01585 case XK_Scroll_Lock:
01586 return kKeyModifierBitScrollLock;
01587
01588 default:
01589 return kKeyModifierBitNone;
01590 }
01591 }
01592
01593 CString
01594 CXWindowsUtil::atomToString(Display* display, Atom atom)
01595 {
01596 if (atom == 0) {
01597 return "None";
01598 }
01599
01600 bool error = false;
01601 CXWindowsUtil::CErrorLock lock(display, &error);
01602 char* name = XGetAtomName(display, atom);
01603 if (error) {
01604 return CStringUtil::print("<UNKNOWN> (%d)", (int)atom);
01605 }
01606 else {
01607 CString msg = CStringUtil::print("%s (%d)", name, (int)atom);
01608 XFree(name);
01609 return msg;
01610 }
01611 }
01612
01613 CString
01614 CXWindowsUtil::atomsToString(Display* display, const Atom* atom, UInt32 num)
01615 {
01616 char** names = new char*[num];
01617 bool error = false;
01618 CXWindowsUtil::CErrorLock lock(display, &error);
01619 XGetAtomNames(display, const_cast<Atom*>(atom), (int)num, names);
01620 CString msg;
01621 if (error) {
01622 for (UInt32 i = 0; i < num; ++i) {
01623 msg += CStringUtil::print("<UNKNOWN> (%d), ", (int)atom[i]);
01624 }
01625 }
01626 else {
01627 for (UInt32 i = 0; i < num; ++i) {
01628 msg += CStringUtil::print("%s (%d), ", names[i], (int)atom[i]);
01629 XFree(names[i]);
01630 }
01631 }
01632 delete[] names;
01633 if (msg.size() > 2) {
01634 msg.erase(msg.size() - 2);
01635 }
01636 return msg;
01637 }
01638
01639 void
01640 CXWindowsUtil::convertAtomProperty(CString& data)
01641 {
01642
01643
01644
01645
01646
01647
01648 if (sizeof(Atom) != 4 && ((data.size() / 4) & 1) != 0) {
01649 UInt32 zero = 0;
01650 data.append(reinterpret_cast<char*>(&zero), sizeof(zero));
01651 }
01652 }
01653
01654 void
01655 CXWindowsUtil::appendAtomData(CString& data, Atom atom)
01656 {
01657 data.append(reinterpret_cast<char*>(&atom), sizeof(Atom));
01658 }
01659
01660 void
01661 CXWindowsUtil::replaceAtomData(CString& data, UInt32 index, Atom atom)
01662 {
01663 data.replace(index * sizeof(Atom), sizeof(Atom),
01664 reinterpret_cast<const char*>(&atom),
01665 sizeof(Atom));
01666 }
01667
01668 void
01669 CXWindowsUtil::appendTimeData(CString& data, Time time)
01670 {
01671 data.append(reinterpret_cast<char*>(&time), sizeof(Time));
01672 }
01673
01674 Bool
01675 CXWindowsUtil::propertyNotifyPredicate(Display*, XEvent* xevent, XPointer arg)
01676 {
01677 CPropertyNotifyPredicateInfo* filter =
01678 reinterpret_cast<CPropertyNotifyPredicateInfo*>(arg);
01679 return (xevent->type == PropertyNotify &&
01680 xevent->xproperty.window == filter->m_window &&
01681 xevent->xproperty.atom == filter->m_property &&
01682 xevent->xproperty.state == PropertyNewValue) ? True : False;
01683 }
01684
01685 void
01686 CXWindowsUtil::initKeyMaps()
01687 {
01688 if (s_keySymToUCS4.empty()) {
01689 for (size_t i =0; i < sizeof(s_keymap) / sizeof(s_keymap[0]); ++i) {
01690 s_keySymToUCS4[s_keymap[i].keysym] = s_keymap[i].ucs4;
01691 }
01692 }
01693 }
01694
01695
01696
01697
01698
01699
01700 CXWindowsUtil::CErrorLock* CXWindowsUtil::CErrorLock::s_top = NULL;
01701
01702 CXWindowsUtil::CErrorLock::CErrorLock(Display* display) :
01703 m_display(display)
01704 {
01705 install(&CXWindowsUtil::CErrorLock::ignoreHandler, NULL);
01706 }
01707
01708 CXWindowsUtil::CErrorLock::CErrorLock(Display* display, bool* flag) :
01709 m_display(display)
01710 {
01711 install(&CXWindowsUtil::CErrorLock::saveHandler, flag);
01712 }
01713
01714 CXWindowsUtil::CErrorLock::CErrorLock(Display* display,
01715 ErrorHandler handler, void* data) :
01716 m_display(display)
01717 {
01718 install(handler, data);
01719 }
01720
01721 CXWindowsUtil::CErrorLock::~CErrorLock()
01722 {
01723
01724 if (m_display != NULL) {
01725 XSync(m_display, False);
01726 }
01727
01728
01729 XSetErrorHandler(m_oldXHandler);
01730 s_top = m_next;
01731 }
01732
01733 void
01734 CXWindowsUtil::CErrorLock::install(ErrorHandler handler, void* data)
01735 {
01736
01737 if (m_display != NULL) {
01738 XSync(m_display, False);
01739 }
01740
01741
01742 m_handler = handler;
01743 m_userData = data;
01744 m_oldXHandler = XSetErrorHandler(
01745 &CXWindowsUtil::CErrorLock::internalHandler);
01746 m_next = s_top;
01747 s_top = this;
01748 }
01749
01750 int
01751 CXWindowsUtil::CErrorLock::internalHandler(Display* display, XErrorEvent* event)
01752 {
01753 if (s_top != NULL && s_top->m_handler != NULL) {
01754 s_top->m_handler(display, event, s_top->m_userData);
01755 }
01756 return 0;
01757 }
01758
01759 void
01760 CXWindowsUtil::CErrorLock::ignoreHandler(Display*, XErrorEvent* e, void*)
01761 {
01762 LOG((CLOG_DEBUG1 "ignoring X error: %d", e->error_code));
01763 }
01764
01765 void
01766 CXWindowsUtil::CErrorLock::saveHandler(Display*, XErrorEvent* e, void* flag)
01767 {
01768 LOG((CLOG_DEBUG1 "flagging X error: %d", e->error_code));
01769 *reinterpret_cast<bool*>(flag) = true;
01770 }