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