| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "remoting/host/linux/keyboard_layout_monitor_utils.h" |
| |
| namespace remoting { |
| |
| // GDK doesn't return unicode value for dead keys, so we map them here. |
| const char* DeadKeyToUtf8String(guint keyval) { |
| // Some of these have spacing forms and some don't. For consistency, these are |
| // all of the form space+combining character. This file is a good resource to |
| // figure out what the various dead keys are supposed to do: |
| // https://cgit.freedesktop.org/xorg/lib/libX11/plain/nls/en_US.UTF-8/Compose.pre |
| // See also ui/events/keycodes/keysym_to_unicode.cc, which does a similar |
| // mapping. |
| switch (keyval) { |
| case GDK_KEY_dead_grave: |
| return " \xcc\x80"; // U+0300 |
| case GDK_KEY_dead_acute: |
| return " \xcc\x81"; // U+0301 |
| case GDK_KEY_dead_circumflex: |
| return " \xcc\x82"; // U+0302 |
| case GDK_KEY_dead_tilde: |
| return " \xcc\x83"; // U+0303 |
| case GDK_KEY_dead_macron: |
| return " \xcc\x84"; // U+0304 |
| case GDK_KEY_dead_breve: |
| return " \xcc\x86"; // U+0306 |
| case GDK_KEY_dead_abovedot: |
| return " \xcc\x87"; // U+0307 |
| case GDK_KEY_dead_diaeresis: |
| return " \xcc\x88"; // U+0308 |
| case GDK_KEY_dead_abovering: |
| return " \xcc\x8a"; // U+030A |
| case GDK_KEY_dead_doubleacute: |
| return " \xcc\x8b"; // U+030B |
| case GDK_KEY_dead_caron: |
| return " \xcc\x8c"; // U+030C |
| case GDK_KEY_dead_cedilla: |
| return " \xcc\xa7"; // U+0327 |
| case GDK_KEY_dead_ogonek: |
| return " \xcc\xa8"; // U+0328 |
| case GDK_KEY_dead_iota: |
| return " \xcd\x85"; // U+0345 |
| case GDK_KEY_dead_voiced_sound: |
| return " \xe3\x82\x99"; // U+3099 |
| case GDK_KEY_dead_semivoiced_sound: |
| return " \xe3\x82\x9a"; // U+309A |
| case GDK_KEY_dead_belowdot: |
| return " \xcc\xa3"; // U+0323 |
| case GDK_KEY_dead_hook: |
| return " \xcc\x89"; // U+0309 |
| case GDK_KEY_dead_horn: |
| return " \xcc\x9b"; // U+031B |
| case GDK_KEY_dead_stroke: |
| return " \xcc\xb7"; // U+0337 |
| case GDK_KEY_dead_abovecomma: |
| return " \xcc\x93"; // U+0313 |
| case GDK_KEY_dead_abovereversedcomma: |
| return " \xcc\x94"; // U+0314 |
| case GDK_KEY_dead_doublegrave: |
| return " \xcc\x8f"; // U+030F |
| case GDK_KEY_dead_belowring: |
| return " \xcc\xa5"; // U+0325 |
| case GDK_KEY_dead_belowmacron: |
| return " \xcc\xb1"; // U+0331 |
| case GDK_KEY_dead_belowcircumflex: |
| return " \xcc\xad"; // U+032D |
| case GDK_KEY_dead_belowtilde: |
| return " \xcc\xb0"; // U+0330 |
| case GDK_KEY_dead_belowbreve: |
| return " \xcc\xae"; // U+032E |
| case GDK_KEY_dead_belowdiaeresis: |
| return " \xcc\xa4"; // U+0324 |
| case GDK_KEY_dead_invertedbreve: |
| return " \xcc\x91"; // U+0311 |
| case GDK_KEY_dead_belowcomma: |
| return " \xcc\xa6"; // U+0326 |
| case GDK_KEY_dead_currency: |
| // This one is a bit different: instead of adding a diacritic to a |
| // character, it allows entering of various currency symbols. E.g., |
| // dead_currency+e generates the euro sign (€). Combining this dead key |
| // with space generates the general currency symbol. |
| return "\xc2\xa4"; // Currency symbol (¤), U+00A4 |
| // I can't find any information about what these do. There is, e.g., |
| // "combining latin small letter a" (U+0363) that places a tiny "a" above |
| // the preceding character (and similar for the other lower-case letters), |
| // but no equivalent capital versions. These don't show up in Compose.pre, |
| // so they're probably not used much, if at all. |
| // case GDK_KEY_dead_a: |
| // case GDK_KEY_dead_A: |
| // case GDK_KEY_dead_e: |
| // case GDK_KEY_dead_E: |
| // case GDK_KEY_dead_i: |
| // case GDK_KEY_dead_I: |
| // case GDK_KEY_dead_o: |
| // case GDK_KEY_dead_O: |
| // case GDK_KEY_dead_u: |
| // case GDK_KEY_dead_U: |
| // case GDK_KEY_dead_small_schwa: |
| // case GDK_KEY_dead_capital_schwa: |
| case GDK_KEY_dead_greek: |
| // Like dead_currency above, this key is used to generate different |
| // symbols entirely (greek letters, in this case). E.g., dead_greek+a |
| // generates Greek alpha (α). Combining this dead key with space generates |
| // the micro sign (µ), a distinct code point from Greek mu (μ), which is |
| // generated by dead_greek+m. |
| return "\xce\xbc"; // Micro symbol (μ), U+00B5 |
| default: |
| return nullptr; |
| } |
| } |
| |
| protocol::LayoutKeyFunction KeyvalToFunction(guint keyval) { |
| switch (keyval) { |
| case GDK_KEY_Control_L: |
| case GDK_KEY_Control_R: |
| return protocol::LayoutKeyFunction::CONTROL; |
| case GDK_KEY_Alt_L: |
| case GDK_KEY_Alt_R: |
| return protocol::LayoutKeyFunction::ALT; |
| case GDK_KEY_Shift_L: |
| case GDK_KEY_Shift_R: |
| return protocol::LayoutKeyFunction::SHIFT; |
| case GDK_KEY_Super_L: |
| case GDK_KEY_Super_R: |
| return protocol::LayoutKeyFunction::META; |
| case GDK_KEY_ISO_Level3_Shift: |
| return protocol::LayoutKeyFunction::ALT_GR; |
| case GDK_KEY_ISO_Level5_Shift: |
| return protocol::LayoutKeyFunction::MOD5; |
| case GDK_KEY_Multi_key: |
| return protocol::LayoutKeyFunction::COMPOSE; |
| case GDK_KEY_Num_Lock: |
| return protocol::LayoutKeyFunction::NUM_LOCK; |
| case GDK_KEY_Caps_Lock: |
| return protocol::LayoutKeyFunction::CAPS_LOCK; |
| case GDK_KEY_Scroll_Lock: |
| return protocol::LayoutKeyFunction::SCROLL_LOCK; |
| case GDK_KEY_BackSpace: |
| return protocol::LayoutKeyFunction::BACKSPACE; |
| case GDK_KEY_Return: |
| case GDK_KEY_KP_Enter: |
| return protocol::LayoutKeyFunction::ENTER; |
| case GDK_KEY_Tab: // Unshifted |
| case GDK_KEY_ISO_Left_Tab: // Shifted |
| case GDK_KEY_KP_Tab: |
| return protocol::LayoutKeyFunction::TAB; |
| case GDK_KEY_Insert: |
| case GDK_KEY_KP_Insert: |
| return protocol::LayoutKeyFunction::INSERT; |
| case GDK_KEY_Delete: |
| case GDK_KEY_KP_Delete: |
| return protocol::LayoutKeyFunction::DELETE_; |
| case GDK_KEY_Home: |
| case GDK_KEY_KP_Home: |
| return protocol::LayoutKeyFunction::HOME; |
| case GDK_KEY_End: |
| case GDK_KEY_KP_End: |
| return protocol::LayoutKeyFunction::END; |
| case GDK_KEY_Page_Up: |
| case GDK_KEY_KP_Page_Up: |
| return protocol::LayoutKeyFunction::PAGE_UP; |
| case GDK_KEY_Page_Down: |
| case GDK_KEY_KP_Page_Down: |
| return protocol::LayoutKeyFunction::PAGE_DOWN; |
| case GDK_KEY_Clear: |
| return protocol::LayoutKeyFunction::CLEAR; |
| case GDK_KEY_Up: |
| case GDK_KEY_KP_Up: |
| return protocol::LayoutKeyFunction::ARROW_UP; |
| case GDK_KEY_Down: |
| case GDK_KEY_KP_Down: |
| return protocol::LayoutKeyFunction::ARROW_DOWN; |
| case GDK_KEY_Left: |
| case GDK_KEY_KP_Left: |
| return protocol::LayoutKeyFunction::ARROW_LEFT; |
| case GDK_KEY_Right: |
| case GDK_KEY_KP_Right: |
| return protocol::LayoutKeyFunction::ARROW_RIGHT; |
| case GDK_KEY_F1: |
| case GDK_KEY_KP_F1: |
| return protocol::LayoutKeyFunction::F1; |
| case GDK_KEY_F2: |
| case GDK_KEY_KP_F2: |
| return protocol::LayoutKeyFunction::F2; |
| case GDK_KEY_F3: |
| case GDK_KEY_KP_F3: |
| return protocol::LayoutKeyFunction::F3; |
| case GDK_KEY_F4: |
| case GDK_KEY_KP_F4: |
| return protocol::LayoutKeyFunction::F4; |
| case GDK_KEY_F5: |
| return protocol::LayoutKeyFunction::F5; |
| case GDK_KEY_F6: |
| return protocol::LayoutKeyFunction::F6; |
| case GDK_KEY_F7: |
| return protocol::LayoutKeyFunction::F7; |
| case GDK_KEY_F8: |
| return protocol::LayoutKeyFunction::F8; |
| case GDK_KEY_F9: |
| return protocol::LayoutKeyFunction::F9; |
| case GDK_KEY_F10: |
| return protocol::LayoutKeyFunction::F10; |
| case GDK_KEY_F11: |
| return protocol::LayoutKeyFunction::F11; |
| case GDK_KEY_F12: |
| return protocol::LayoutKeyFunction::F12; |
| case GDK_KEY_F13: |
| return protocol::LayoutKeyFunction::F13; |
| case GDK_KEY_F14: |
| return protocol::LayoutKeyFunction::F14; |
| case GDK_KEY_F15: |
| return protocol::LayoutKeyFunction::F15; |
| case GDK_KEY_F16: |
| return protocol::LayoutKeyFunction::F16; |
| case GDK_KEY_F17: |
| return protocol::LayoutKeyFunction::F17; |
| case GDK_KEY_F18: |
| return protocol::LayoutKeyFunction::F18; |
| case GDK_KEY_F19: |
| return protocol::LayoutKeyFunction::F19; |
| case GDK_KEY_F20: |
| return protocol::LayoutKeyFunction::F20; |
| case GDK_KEY_F21: |
| return protocol::LayoutKeyFunction::F21; |
| case GDK_KEY_F22: |
| return protocol::LayoutKeyFunction::F22; |
| case GDK_KEY_F23: |
| return protocol::LayoutKeyFunction::F23; |
| case GDK_KEY_F24: |
| return protocol::LayoutKeyFunction::F24; |
| case GDK_KEY_Escape: |
| return protocol::LayoutKeyFunction::ESCAPE; |
| case GDK_KEY_Menu: |
| return protocol::LayoutKeyFunction::CONTEXT_MENU; |
| case GDK_KEY_Pause: |
| return protocol::LayoutKeyFunction::PAUSE; |
| case GDK_KEY_Print: // Unshifted |
| case GDK_KEY_Sys_Req: // Shifted |
| return protocol::LayoutKeyFunction::PRINT_SCREEN; |
| case GDK_KEY_Zenkaku_Hankaku: // Unshifted |
| case GDK_KEY_Kanji: // Shifted |
| return protocol::LayoutKeyFunction::HANKAKU_ZENKAKU_KANJI; |
| case GDK_KEY_Henkan: |
| return protocol::LayoutKeyFunction::HENKAN; |
| case GDK_KEY_Muhenkan: |
| return protocol::LayoutKeyFunction::MUHENKAN; |
| case GDK_KEY_Hiragana_Katakana: // Unshifted |
| case GDK_KEY_Romaji: // Shifted |
| return protocol::KATAKANA_HIRAGANA_ROMAJI; |
| case GDK_KEY_Eisu_toggle: |
| return protocol::LayoutKeyFunction::EISU; |
| case GDK_KEY_Hangul: |
| return protocol::LayoutKeyFunction::HAN_YEONG; |
| case GDK_KEY_Hangul_Hanja: |
| return protocol::LayoutKeyFunction::HANJA; |
| default: |
| return protocol::LayoutKeyFunction::UNKNOWN; |
| } |
| } |
| |
| } // namespace remoting |