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 "ui/events/keycodes/keyboard_code_conversion_xkb.h" 6 7 #include "build/build_config.h" 8 #include "ui/events/keycodes/dom/dom_key.h" 9 #include "ui/events/keycodes/keyboard_code_conversion_xkb.h" 10 #include "ui/gfx/x/keysyms/keysyms.h" 11 12 namespace ui { 13 14 // We support dead keys beyond those with predefined keysym names, 15 // expressed as numeric constants with |kDeadKeyFlag| set. 16 // Xkbcommon accepts and does not use any bits in 0x0E000000. 17 // 18 constexpr xkb_keysym_t kDeadKeyFlag = 0x08000000; 19 constexpr int32_t kUnicodeMax = 0x10FFFF; 20 NonPrintableXKeySymToDomKey(xkb_keysym_t keysym)21DomKey NonPrintableXKeySymToDomKey(xkb_keysym_t keysym) { 22 switch (keysym) { 23 case XKB_KEY_BackSpace: 24 return DomKey::BACKSPACE; 25 case XKB_KEY_Tab: 26 case XKB_KEY_KP_Tab: 27 case XKB_KEY_ISO_Left_Tab: 28 return DomKey::TAB; 29 case XKB_KEY_Clear: 30 case XKB_KEY_KP_Begin: 31 case XKB_KEY_XF86Clear: 32 return DomKey::CLEAR; 33 case XKB_KEY_Return: 34 case XKB_KEY_KP_Enter: 35 return DomKey::ENTER; 36 case XKB_KEY_Linefeed: 37 return DomKey::ENTER; 38 case XKB_KEY_Pause: 39 return DomKey::PAUSE; 40 case XKB_KEY_Scroll_Lock: 41 return DomKey::SCROLL_LOCK; 42 case XKB_KEY_Escape: 43 return DomKey::ESCAPE; 44 case XKB_KEY_Multi_key: 45 return DomKey::COMPOSE; 46 case XKB_KEY_Kanji: 47 return DomKey::KANJI_MODE; 48 case XKB_KEY_Muhenkan: 49 return DomKey::NON_CONVERT; 50 case XKB_KEY_Henkan_Mode: 51 return DomKey::CONVERT; 52 case XKB_KEY_Romaji: 53 return DomKey::ROMAJI; 54 case XKB_KEY_Hiragana: 55 return DomKey::HIRAGANA; 56 case XKB_KEY_Katakana: 57 return DomKey::KATAKANA; 58 case XKB_KEY_Hiragana_Katakana: 59 return DomKey::HIRAGANA_KATAKANA; 60 case XKB_KEY_Zenkaku: 61 return DomKey::ZENKAKU; 62 case XKB_KEY_Hankaku: 63 return DomKey::HANKAKU; 64 case XKB_KEY_Zenkaku_Hankaku: 65 return DomKey::ZENKAKU_HANKAKU; 66 case XKB_KEY_Kana_Lock: 67 return DomKey::KANA_MODE; 68 case XKB_KEY_Eisu_Shift: 69 case XKB_KEY_Eisu_toggle: 70 return DomKey::ALPHANUMERIC; 71 case XKB_KEY_Hangul: 72 return DomKey::HANGUL_MODE; 73 case XKB_KEY_Hangul_Hanja: 74 return DomKey::HANJA_MODE; 75 case XKB_KEY_Codeinput: 76 return DomKey::CODE_INPUT; 77 case XKB_KEY_SingleCandidate: 78 return DomKey::SINGLE_CANDIDATE; 79 case XKB_KEY_MultipleCandidate: 80 return DomKey::ALL_CANDIDATES; 81 case XKB_KEY_PreviousCandidate: 82 return DomKey::PREVIOUS_CANDIDATE; 83 case XKB_KEY_Home: 84 case XKB_KEY_KP_Home: 85 return DomKey::HOME; 86 case XKB_KEY_Left: 87 case XKB_KEY_KP_Left: 88 return DomKey::ARROW_LEFT; 89 case XKB_KEY_Up: 90 case XKB_KEY_KP_Up: 91 return DomKey::ARROW_UP; 92 case XKB_KEY_Right: 93 case XKB_KEY_KP_Right: 94 return DomKey::ARROW_RIGHT; 95 case XKB_KEY_Down: 96 case XKB_KEY_KP_Down: 97 return DomKey::ARROW_DOWN; 98 case XKB_KEY_Prior: 99 case XKB_KEY_KP_Prior: 100 return DomKey::PAGE_UP; 101 case XKB_KEY_Next: 102 case XKB_KEY_KP_Next: 103 case XKB_KEY_XF86ScrollDown: 104 return DomKey::PAGE_DOWN; 105 case XKB_KEY_End: 106 case XKB_KEY_KP_End: 107 case XKB_KEY_XF86ScrollUp: 108 return DomKey::END; 109 case XKB_KEY_Select: 110 return DomKey::SELECT; 111 // Treat Print/PrintScreen as PrintScreen https://crbug.com/683097. 112 case XKB_KEY_Print: 113 case XKB_KEY_3270_PrintScreen: 114 return DomKey::PRINT_SCREEN; 115 case XKB_KEY_Execute: 116 return DomKey::EXECUTE; 117 case XKB_KEY_Insert: 118 case XKB_KEY_KP_Insert: 119 return DomKey::INSERT; 120 case XKB_KEY_Undo: 121 return DomKey::UNDO; 122 case XKB_KEY_Redo: 123 return DomKey::REDO; 124 case XKB_KEY_Menu: 125 return DomKey::CONTEXT_MENU; 126 case XKB_KEY_Find: 127 return DomKey::FIND; 128 case XKB_KEY_Cancel: 129 return DomKey::CANCEL; 130 case XKB_KEY_Help: 131 return DomKey::HELP; 132 case XKB_KEY_Break: 133 case XKB_KEY_3270_Attn: 134 return DomKey::ATTN; 135 case XKB_KEY_Mode_switch: 136 return DomKey::MODE_CHANGE; 137 case XKB_KEY_Num_Lock: 138 return DomKey::NUM_LOCK; 139 case XKB_KEY_F1: 140 case XKB_KEY_KP_F1: 141 return DomKey::F1; 142 case XKB_KEY_F2: 143 case XKB_KEY_KP_F2: 144 return DomKey::F2; 145 case XKB_KEY_F3: 146 case XKB_KEY_KP_F3: 147 return DomKey::F3; 148 case XKB_KEY_F4: 149 case XKB_KEY_KP_F4: 150 return DomKey::F4; 151 case XKB_KEY_F5: 152 return DomKey::F5; 153 case XKB_KEY_F6: 154 return DomKey::F6; 155 case XKB_KEY_F7: 156 return DomKey::F7; 157 case XKB_KEY_F8: 158 return DomKey::F8; 159 case XKB_KEY_F9: 160 return DomKey::F9; 161 case XKB_KEY_F10: 162 return DomKey::F10; 163 case XKB_KEY_F11: 164 return DomKey::F11; 165 case XKB_KEY_F12: 166 return DomKey::F12; 167 case XKB_KEY_XF86Tools: // XKB 'inet' mapping of F13 168 case XKB_KEY_F13: 169 return DomKey::F13; 170 case XKB_KEY_F14: 171 case XKB_KEY_XF86Launch5: // XKB 'inet' mapping of F14 172 return DomKey::F14; 173 case XKB_KEY_F15: 174 case XKB_KEY_XF86Launch6: // XKB 'inet' mapping of F15 175 return DomKey::F15; 176 case XKB_KEY_F16: 177 case XKB_KEY_XF86Launch7: // XKB 'inet' mapping of F16 178 return DomKey::F16; 179 case XKB_KEY_F17: 180 case XKB_KEY_XF86Launch8: // XKB 'inet' mapping of F17 181 return DomKey::F17; 182 case XKB_KEY_F18: 183 case XKB_KEY_XF86Launch9: // XKB 'inet' mapping of F18 184 return DomKey::F18; 185 case XKB_KEY_F19: 186 return DomKey::F19; 187 case XKB_KEY_F20: 188 return DomKey::F20; 189 case XKB_KEY_F21: 190 return DomKey::F21; 191 case XKB_KEY_F22: 192 return DomKey::F22; 193 case XKB_KEY_F23: 194 return DomKey::F23; 195 case XKB_KEY_F24: 196 return DomKey::F24; 197 case XKB_KEY_Shift_L: 198 case XKB_KEY_Shift_R: 199 return DomKey::SHIFT; 200 case XKB_KEY_Control_L: 201 case XKB_KEY_Control_R: 202 return DomKey::CONTROL; 203 case XKB_KEY_Caps_Lock: 204 return DomKey::CAPS_LOCK; 205 #if defined(OS_CHROMEOS) 206 case XKB_KEY_Meta_L: 207 case XKB_KEY_Meta_R: 208 case XKB_KEY_Alt_L: 209 case XKB_KEY_Alt_R: 210 // The Shift+Alt generates a KeySym for the Meta key. On ChromeOS the Meta 211 // key is not used and we should still get the Alt key. crbug.com/541468. 212 return DomKey::ALT; 213 #else 214 case XKB_KEY_Meta_L: 215 case XKB_KEY_Meta_R: 216 return DomKey::META; 217 case XKB_KEY_Alt_L: 218 case XKB_KEY_Alt_R: 219 return DomKey::ALT; 220 #endif // defined(OS_CHROMEOS) 221 case XKB_KEY_Super_L: 222 case XKB_KEY_Super_R: 223 return DomKey::META; 224 case XKB_KEY_Hyper_L: 225 case XKB_KEY_Hyper_R: 226 return DomKey::HYPER; 227 case XKB_KEY_Delete: 228 return DomKey::DEL; 229 case XKB_KEY_SunProps: 230 return DomKey::PROPS; 231 case XKB_KEY_XF86Next_VMode: 232 return DomKey::VIDEO_MODE_NEXT; 233 case XKB_KEY_XF86MonBrightnessUp: 234 return DomKey::BRIGHTNESS_UP; 235 case XKB_KEY_XF86MonBrightnessDown: 236 return DomKey::BRIGHTNESS_DOWN; 237 case XKB_KEY_XF86Standby: 238 case XKB_KEY_XF86Sleep: 239 case XKB_KEY_XF86Suspend: 240 return DomKey::STANDBY; 241 case XKB_KEY_XF86AudioLowerVolume: 242 return DomKey::AUDIO_VOLUME_DOWN; 243 case XKB_KEY_XF86AudioMute: 244 return DomKey::AUDIO_VOLUME_MUTE; 245 case XKB_KEY_XF86AudioRaiseVolume: 246 return DomKey::AUDIO_VOLUME_UP; 247 case XKB_KEY_XF86AudioPlay: 248 return DomKey::MEDIA_PLAY_PAUSE; 249 case XKB_KEY_XF86AudioStop: 250 return DomKey::MEDIA_STOP; 251 case XKB_KEY_XF86AudioPrev: 252 return DomKey::MEDIA_TRACK_PREVIOUS; 253 case XKB_KEY_XF86AudioNext: 254 return DomKey::MEDIA_TRACK_NEXT; 255 case XKB_KEY_XF86HomePage: 256 return DomKey::BROWSER_HOME; 257 case XKB_KEY_XF86Mail: 258 return DomKey::LAUNCH_MAIL; 259 case XKB_KEY_XF86Search: 260 return DomKey::BROWSER_SEARCH; 261 case XKB_KEY_XF86AudioRecord: 262 return DomKey::MEDIA_RECORD; 263 case XKB_KEY_XF86Calculator: 264 return DomKey::LAUNCH_CALCULATOR; 265 case XKB_KEY_XF86Calendar: 266 return DomKey::LAUNCH_CALENDAR; 267 case XKB_KEY_XF86Back: 268 return DomKey::BROWSER_BACK; 269 case XKB_KEY_XF86Forward: 270 return DomKey::BROWSER_FORWARD; 271 case XKB_KEY_XF86Stop: 272 return DomKey::BROWSER_STOP; 273 case XKB_KEY_XF86Refresh: 274 case XKB_KEY_XF86Reload: 275 return DomKey::BROWSER_REFRESH; 276 case XKB_KEY_XF86PowerOff: 277 return DomKey::POWER_OFF; 278 case XKB_KEY_XF86WakeUp: 279 return DomKey::WAKE_UP; 280 case XKB_KEY_XF86Eject: 281 return DomKey::EJECT; 282 case XKB_KEY_XF86ScreenSaver: 283 return DomKey::LAUNCH_SCREEN_SAVER; 284 case XKB_KEY_XF86WWW: 285 return DomKey::LAUNCH_WEB_BROWSER; 286 case XKB_KEY_XF86Favorites: 287 return DomKey::BROWSER_FAVORITES; 288 case XKB_KEY_XF86AudioPause: 289 return DomKey::MEDIA_PAUSE; 290 case XKB_KEY_XF86AudioMedia: 291 case XKB_KEY_XF86Music: 292 return DomKey::LAUNCH_MUSIC_PLAYER; 293 case XKB_KEY_XF86MyComputer: 294 case XKB_KEY_XF86Explorer: 295 return DomKey::LAUNCH_MY_COMPUTER; 296 case XKB_KEY_XF86AudioRewind: 297 return DomKey::MEDIA_REWIND; 298 case XKB_KEY_XF86CD: 299 case XKB_KEY_XF86Video: 300 return DomKey::LAUNCH_MEDIA_PLAYER; 301 case XKB_KEY_XF86Close: 302 return DomKey::CLOSE; 303 case XKB_KEY_XF86Copy: 304 case XKB_KEY_SunCopy: 305 return DomKey::COPY; 306 case XKB_KEY_XF86Cut: 307 case XKB_KEY_SunCut: 308 return DomKey::CUT; 309 case XKB_KEY_XF86Display: 310 return DomKey::DISPLAY_SWAP; 311 case XKB_KEY_XF86Excel: 312 return DomKey::LAUNCH_SPREADSHEET; 313 case XKB_KEY_XF86LogOff: 314 return DomKey::LOG_OFF; 315 case XKB_KEY_XF86New: 316 return DomKey::NEW; 317 case XKB_KEY_XF86Open: 318 case XKB_KEY_SunOpen: 319 return DomKey::OPEN; 320 case XKB_KEY_XF86Paste: 321 case XKB_KEY_SunPaste: 322 return DomKey::PASTE; 323 case XKB_KEY_XF86Reply: 324 return DomKey::MAIL_REPLY; 325 case XKB_KEY_XF86Save: 326 return DomKey::SAVE; 327 case XKB_KEY_XF86Send: 328 return DomKey::MAIL_SEND; 329 case XKB_KEY_XF86Spell: 330 return DomKey::SPELL_CHECK; 331 case XKB_KEY_XF86SplitScreen: 332 return DomKey::SPLIT_SCREEN_TOGGLE; 333 case XKB_KEY_XF86Word: 334 case XKB_KEY_XF86OfficeHome: 335 return DomKey::LAUNCH_WORD_PROCESSOR; 336 case XKB_KEY_XF86ZoomIn: 337 return DomKey::ZOOM_IN; 338 case XKB_KEY_XF86ZoomOut: 339 return DomKey::ZOOM_OUT; 340 case XKB_KEY_XF86WebCam: 341 return DomKey::LAUNCH_WEB_CAM; 342 case XKB_KEY_XF86MailForward: 343 return DomKey::MAIL_FORWARD; 344 case XKB_KEY_XF86AudioForward: 345 return DomKey::MEDIA_FAST_FORWARD; 346 case XKB_KEY_XF86AudioRandomPlay: 347 return DomKey::RANDOM_TOGGLE; 348 case XKB_KEY_XF86Subtitle: 349 return DomKey::SUBTITLE; 350 case XKB_KEY_XF86Hibernate: 351 return DomKey::HIBERNATE; 352 case XKB_KEY_3270_EraseEOF: 353 return DomKey::ERASE_EOF; 354 case XKB_KEY_3270_Play: 355 return DomKey::PLAY; 356 case XKB_KEY_3270_ExSelect: 357 return DomKey::EX_SEL; 358 case XKB_KEY_3270_CursorSelect: 359 return DomKey::CR_SEL; 360 case XKB_KEY_ISO_Level3_Shift: 361 return DomKey::ALT_GRAPH; 362 case XKB_KEY_ISO_Level3_Latch: 363 return DomKey::ALT_GRAPH_LATCH; 364 case XKB_KEY_ISO_Level5_Shift: 365 return DomKey::SHIFT_LEVEL5; 366 case XKB_KEY_ISO_Next_Group: 367 return DomKey::GROUP_NEXT; 368 case XKB_KEY_ISO_Prev_Group: 369 return DomKey::GROUP_PREVIOUS; 370 case XKB_KEY_ISO_First_Group: 371 return DomKey::GROUP_FIRST; 372 case XKB_KEY_ISO_Last_Group: 373 return DomKey::GROUP_LAST; 374 case XKB_KEY_dead_grave: 375 // combining grave accent 376 return DomKey::DeadKeyFromCombiningCharacter(0x0300); 377 case XKB_KEY_dead_acute: 378 // combining acute accent 379 return DomKey::DeadKeyFromCombiningCharacter(0x0301); 380 case XKB_KEY_dead_circumflex: 381 // combining circumflex accent 382 return DomKey::DeadKeyFromCombiningCharacter(0x0302); 383 case XKB_KEY_dead_tilde: 384 // combining tilde 385 return DomKey::DeadKeyFromCombiningCharacter(0x0303); 386 case XKB_KEY_dead_macron: 387 // combining macron 388 return DomKey::DeadKeyFromCombiningCharacter(0x0304); 389 case XKB_KEY_dead_breve: 390 // combining breve 391 return DomKey::DeadKeyFromCombiningCharacter(0x0306); 392 case XKB_KEY_dead_abovedot: 393 // combining dot above 394 return DomKey::DeadKeyFromCombiningCharacter(0x0307); 395 case XKB_KEY_dead_diaeresis: 396 // combining diaeresis 397 return DomKey::DeadKeyFromCombiningCharacter(0x0308); 398 case XKB_KEY_dead_abovering: 399 // combining ring above 400 return DomKey::DeadKeyFromCombiningCharacter(0x030A); 401 case XKB_KEY_dead_doubleacute: 402 // combining double acute accent 403 return DomKey::DeadKeyFromCombiningCharacter(0x030B); 404 case XKB_KEY_dead_caron: 405 // combining caron 406 return DomKey::DeadKeyFromCombiningCharacter(0x030C); 407 case XKB_KEY_dead_cedilla: 408 // combining cedilla 409 return DomKey::DeadKeyFromCombiningCharacter(0x0327); 410 case XKB_KEY_dead_ogonek: 411 // combining ogonek 412 return DomKey::DeadKeyFromCombiningCharacter(0x0328); 413 case XKB_KEY_dead_iota: 414 // combining greek ypogegrammeni 415 return DomKey::DeadKeyFromCombiningCharacter(0x0345); 416 case XKB_KEY_dead_voiced_sound: 417 // combining voiced sound mark 418 return DomKey::DeadKeyFromCombiningCharacter(0x3099); 419 case XKB_KEY_dead_semivoiced_sound: 420 // combining semi-voiced sound mark 421 return DomKey::DeadKeyFromCombiningCharacter(0x309A); 422 case XKB_KEY_dead_belowdot: 423 // combining dot below 424 return DomKey::DeadKeyFromCombiningCharacter(0x0323); 425 case XKB_KEY_dead_hook: 426 // combining hook above 427 return DomKey::DeadKeyFromCombiningCharacter(0x0309); 428 case XKB_KEY_dead_horn: 429 // combining horn 430 return DomKey::DeadKeyFromCombiningCharacter(0x031B); 431 case XKB_KEY_dead_stroke: 432 // combining long solidus overlay 433 return DomKey::DeadKeyFromCombiningCharacter(0x0338); 434 case XKB_KEY_dead_abovecomma: 435 // combining comma above 436 return DomKey::DeadKeyFromCombiningCharacter(0x0313); 437 case XKB_KEY_dead_abovereversedcomma: 438 // combining reversed comma above 439 return DomKey::DeadKeyFromCombiningCharacter(0x0314); 440 case XKB_KEY_dead_doublegrave: 441 // combining double grave accent 442 return DomKey::DeadKeyFromCombiningCharacter(0x030F); 443 case XKB_KEY_dead_belowring: 444 // combining ring below 445 return DomKey::DeadKeyFromCombiningCharacter(0x0325); 446 case XKB_KEY_dead_belowmacron: 447 // combining macron below 448 return DomKey::DeadKeyFromCombiningCharacter(0x0331); 449 case XKB_KEY_dead_belowcircumflex: 450 // combining circumflex accent below 451 return DomKey::DeadKeyFromCombiningCharacter(0x032D); 452 case XKB_KEY_dead_belowtilde: 453 // combining tilde below 454 return DomKey::DeadKeyFromCombiningCharacter(0x0330); 455 case XKB_KEY_dead_belowbreve: 456 // combining breve below 457 return DomKey::DeadKeyFromCombiningCharacter(0x032E); 458 case XKB_KEY_dead_belowdiaeresis: 459 // combining diaeresis below 460 return DomKey::DeadKeyFromCombiningCharacter(0x0324); 461 case XKB_KEY_dead_invertedbreve: 462 // combining inverted breve 463 return DomKey::DeadKeyFromCombiningCharacter(0x0311); 464 case XKB_KEY_dead_belowcomma: 465 // combining comma below 466 return DomKey::DeadKeyFromCombiningCharacter(0x0326); 467 case XKB_KEY_dead_currency: 468 // currency sign 469 return DomKey::DeadKeyFromCombiningCharacter(0x00A4); 470 case XKB_KEY_dead_greek: 471 // greek question mark 472 return DomKey::DeadKeyFromCombiningCharacter(0x037E); 473 default: 474 if (keysym & kDeadKeyFlag) { 475 int32_t character = keysym & ~kDeadKeyFlag; 476 if ((character >= 0) && (character <= kUnicodeMax)) { 477 return DomKey::DeadKeyFromCombiningCharacter(character); 478 } 479 } 480 return DomKey::NONE; 481 } 482 } XKeySymToDomKey(xkb_keysym_t keysym,base::char16 character)483DomKey XKeySymToDomKey(xkb_keysym_t keysym, base::char16 character) { 484 DomKey dom_key = NonPrintableXKeySymToDomKey(keysym); 485 if (dom_key != DomKey::NONE) 486 return dom_key; 487 return DomKey::FromCharacter(character); 488 } 489 490 } // namespace ui 491