blob: 4b95e75a497561be62fd0830a17f877b11a50c2c [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/events/keycodes/keyboard_code_conversion_xkb.h"
#include "build/build_config.h"
#include "ui/events/keycodes/dom/dom_key.h"
#ifndef XK_dead_greek
#define XK_dead_greek 0xfe8c
#endif
namespace ui {
// We support dead keys beyond those with predefined keysym names,
// expressed as numeric constants with |kDeadKeyFlag| set.
// Xkbcommon accepts and does not use any bits in 0x0E000000.
//
constexpr xkb_keysym_t kDeadKeyFlag = 0x08000000;
constexpr int32_t kUnicodeMax = 0x10FFFF;
DomKey NonPrintableXKeySymToDomKey(xkb_keysym_t keysym) {
switch (keysym) {
case XKB_KEY_BackSpace:
return DomKey::BACKSPACE;
case XKB_KEY_Tab:
case XKB_KEY_KP_Tab:
case XKB_KEY_ISO_Left_Tab:
return DomKey::TAB;
case XKB_KEY_Clear:
case XKB_KEY_KP_Begin:
case XKB_KEY_XF86Clear:
return DomKey::CLEAR;
case XKB_KEY_Return:
case XKB_KEY_KP_Enter:
return DomKey::ENTER;
case XKB_KEY_Linefeed:
return DomKey::ENTER;
case XKB_KEY_Pause:
return DomKey::PAUSE;
case XKB_KEY_Scroll_Lock:
return DomKey::SCROLL_LOCK;
case XKB_KEY_Escape:
return DomKey::ESCAPE;
case XKB_KEY_Multi_key:
return DomKey::COMPOSE;
case XKB_KEY_Kanji:
return DomKey::KANJI_MODE;
case XKB_KEY_Muhenkan:
return DomKey::NON_CONVERT;
case XKB_KEY_Henkan_Mode:
return DomKey::CONVERT;
case XKB_KEY_Romaji:
return DomKey::ROMAJI;
case XKB_KEY_Hiragana:
return DomKey::HIRAGANA;
case XKB_KEY_Katakana:
return DomKey::KATAKANA;
case XKB_KEY_Hiragana_Katakana:
return DomKey::HIRAGANA_KATAKANA;
case XKB_KEY_Zenkaku:
return DomKey::ZENKAKU;
case XKB_KEY_Hankaku:
return DomKey::HANKAKU;
case XKB_KEY_Zenkaku_Hankaku:
return DomKey::ZENKAKU_HANKAKU;
case XKB_KEY_Kana_Lock:
return DomKey::KANA_MODE;
case XKB_KEY_Eisu_Shift:
case XKB_KEY_Eisu_toggle:
return DomKey::ALPHANUMERIC;
case XKB_KEY_Hangul:
return DomKey::HANGUL_MODE;
case XKB_KEY_Hangul_Hanja:
return DomKey::HANJA_MODE;
case XKB_KEY_Codeinput:
return DomKey::CODE_INPUT;
case XKB_KEY_SingleCandidate:
return DomKey::SINGLE_CANDIDATE;
case XKB_KEY_MultipleCandidate:
return DomKey::ALL_CANDIDATES;
case XKB_KEY_PreviousCandidate:
return DomKey::PREVIOUS_CANDIDATE;
case XKB_KEY_Home:
case XKB_KEY_KP_Home:
return DomKey::HOME;
case XKB_KEY_Left:
case XKB_KEY_KP_Left:
return DomKey::ARROW_LEFT;
case XKB_KEY_Up:
case XKB_KEY_KP_Up:
return DomKey::ARROW_UP;
case XKB_KEY_Right:
case XKB_KEY_KP_Right:
return DomKey::ARROW_RIGHT;
case XKB_KEY_Down:
case XKB_KEY_KP_Down:
return DomKey::ARROW_DOWN;
case XKB_KEY_Prior:
case XKB_KEY_KP_Prior:
return DomKey::PAGE_UP;
case XKB_KEY_Next:
case XKB_KEY_KP_Next:
case XKB_KEY_XF86ScrollDown:
return DomKey::PAGE_DOWN;
case XKB_KEY_End:
case XKB_KEY_KP_End:
case XKB_KEY_XF86ScrollUp:
return DomKey::END;
case XKB_KEY_Select:
return DomKey::SELECT;
// Treat Print/PrintScreen as PrintScreen https://crbug.com/683097.
case XKB_KEY_Print:
case XKB_KEY_3270_PrintScreen:
return DomKey::PRINT_SCREEN;
case XKB_KEY_Execute:
return DomKey::EXECUTE;
case XKB_KEY_Insert:
case XKB_KEY_KP_Insert:
return DomKey::INSERT;
case XKB_KEY_Undo:
return DomKey::UNDO;
case XKB_KEY_Redo:
return DomKey::REDO;
case XKB_KEY_Menu:
return DomKey::CONTEXT_MENU;
case XKB_KEY_Find:
return DomKey::FIND;
case XKB_KEY_Cancel:
return DomKey::CANCEL;
case XKB_KEY_Help:
return DomKey::HELP;
case XKB_KEY_Break:
case XKB_KEY_3270_Attn:
return DomKey::ATTN;
case XKB_KEY_Mode_switch:
return DomKey::MODE_CHANGE;
case XKB_KEY_Num_Lock:
return DomKey::NUM_LOCK;
case XKB_KEY_F1:
case XKB_KEY_KP_F1:
return DomKey::F1;
case XKB_KEY_F2:
case XKB_KEY_KP_F2:
return DomKey::F2;
case XKB_KEY_F3:
case XKB_KEY_KP_F3:
return DomKey::F3;
case XKB_KEY_F4:
case XKB_KEY_KP_F4:
return DomKey::F4;
case XKB_KEY_F5:
return DomKey::F5;
case XKB_KEY_F6:
return DomKey::F6;
case XKB_KEY_F7:
return DomKey::F7;
case XKB_KEY_F8:
return DomKey::F8;
case XKB_KEY_F9:
return DomKey::F9;
case XKB_KEY_F10:
return DomKey::F10;
case XKB_KEY_F11:
return DomKey::F11;
case XKB_KEY_F12:
return DomKey::F12;
case XKB_KEY_XF86Tools: // XKB 'inet' mapping of F13
case XKB_KEY_F13:
return DomKey::F13;
case XKB_KEY_F14:
case XKB_KEY_XF86Launch5: // XKB 'inet' mapping of F14
return DomKey::F14;
case XKB_KEY_F15:
case XKB_KEY_XF86Launch6: // XKB 'inet' mapping of F15
return DomKey::F15;
case XKB_KEY_F16:
case XKB_KEY_XF86Launch7: // XKB 'inet' mapping of F16
return DomKey::F16;
case XKB_KEY_F17:
case XKB_KEY_XF86Launch8: // XKB 'inet' mapping of F17
return DomKey::F17;
case XKB_KEY_F18:
case XKB_KEY_XF86Launch9: // XKB 'inet' mapping of F18
return DomKey::F18;
case XKB_KEY_F19:
return DomKey::F19;
case XKB_KEY_F20:
return DomKey::F20;
case XKB_KEY_F21:
return DomKey::F21;
case XKB_KEY_F22:
return DomKey::F22;
case XKB_KEY_F23:
return DomKey::F23;
case XKB_KEY_F24:
return DomKey::F24;
case XKB_KEY_Shift_L:
case XKB_KEY_Shift_R:
return DomKey::SHIFT;
case XKB_KEY_Control_L:
case XKB_KEY_Control_R:
return DomKey::CONTROL;
case XKB_KEY_Caps_Lock:
return DomKey::CAPS_LOCK;
#if defined(OS_CHROMEOS)
case XKB_KEY_Meta_L:
case XKB_KEY_Meta_R:
case XKB_KEY_Alt_L:
case XKB_KEY_Alt_R:
// The Shift+Alt generates a KeySym for the Meta key. On ChromeOS the Meta
// key is not used and we should still get the Alt key. crbug.com/541468.
return DomKey::ALT;
#else
case XKB_KEY_Meta_L:
case XKB_KEY_Meta_R:
return DomKey::META;
case XKB_KEY_Alt_L:
case XKB_KEY_Alt_R:
return DomKey::ALT;
#endif // defined(OS_CHROMEOS)
case XKB_KEY_Super_L:
case XKB_KEY_Super_R:
return DomKey::META;
case XKB_KEY_Hyper_L:
case XKB_KEY_Hyper_R:
return DomKey::HYPER;
case XKB_KEY_Delete:
return DomKey::DEL;
case XKB_KEY_SunProps:
return DomKey::PROPS;
case XKB_KEY_XF86Next_VMode:
return DomKey::VIDEO_MODE_NEXT;
case XKB_KEY_XF86MonBrightnessUp:
return DomKey::BRIGHTNESS_UP;
case XKB_KEY_XF86MonBrightnessDown:
return DomKey::BRIGHTNESS_DOWN;
case XKB_KEY_XF86Standby:
case XKB_KEY_XF86Sleep:
case XKB_KEY_XF86Suspend:
return DomKey::STANDBY;
case XKB_KEY_XF86AudioLowerVolume:
return DomKey::AUDIO_VOLUME_DOWN;
case XKB_KEY_XF86AudioMute:
return DomKey::AUDIO_VOLUME_MUTE;
case XKB_KEY_XF86AudioRaiseVolume:
return DomKey::AUDIO_VOLUME_UP;
case XKB_KEY_XF86AudioPlay:
return DomKey::MEDIA_PLAY_PAUSE;
case XKB_KEY_XF86AudioStop:
return DomKey::MEDIA_STOP;
case XKB_KEY_XF86AudioPrev:
return DomKey::MEDIA_TRACK_PREVIOUS;
case XKB_KEY_XF86AudioNext:
return DomKey::MEDIA_TRACK_NEXT;
case XKB_KEY_XF86HomePage:
return DomKey::BROWSER_HOME;
case XKB_KEY_XF86Mail:
return DomKey::LAUNCH_MAIL;
case XKB_KEY_XF86Search:
return DomKey::BROWSER_SEARCH;
case XKB_KEY_XF86AudioRecord:
return DomKey::MEDIA_RECORD;
case XKB_KEY_XF86Calculator:
return DomKey::LAUNCH_CALCULATOR;
case XKB_KEY_XF86Calendar:
return DomKey::LAUNCH_CALENDAR;
case XKB_KEY_XF86Back:
return DomKey::BROWSER_BACK;
case XKB_KEY_XF86Forward:
return DomKey::BROWSER_FORWARD;
case XKB_KEY_XF86Stop:
return DomKey::BROWSER_STOP;
case XKB_KEY_XF86Refresh:
case XKB_KEY_XF86Reload:
return DomKey::BROWSER_REFRESH;
case XKB_KEY_XF86PowerOff:
return DomKey::POWER_OFF;
case XKB_KEY_XF86WakeUp:
return DomKey::WAKE_UP;
case XKB_KEY_XF86Eject:
return DomKey::EJECT;
case XKB_KEY_XF86ScreenSaver:
return DomKey::LAUNCH_SCREEN_SAVER;
case XKB_KEY_XF86WWW:
return DomKey::LAUNCH_WEB_BROWSER;
case XKB_KEY_XF86Favorites:
return DomKey::BROWSER_FAVORITES;
case XKB_KEY_XF86AudioPause:
return DomKey::MEDIA_PAUSE;
case XKB_KEY_XF86AudioMedia:
case XKB_KEY_XF86Music:
return DomKey::LAUNCH_MUSIC_PLAYER;
case XKB_KEY_XF86MyComputer:
case XKB_KEY_XF86Explorer:
return DomKey::LAUNCH_MY_COMPUTER;
case XKB_KEY_XF86AudioRewind:
return DomKey::MEDIA_REWIND;
case XKB_KEY_XF86CD:
case XKB_KEY_XF86Video:
return DomKey::LAUNCH_MEDIA_PLAYER;
case XKB_KEY_XF86Close:
return DomKey::CLOSE;
case XKB_KEY_XF86Copy:
case XKB_KEY_SunCopy:
return DomKey::COPY;
case XKB_KEY_XF86Cut:
case XKB_KEY_SunCut:
return DomKey::CUT;
case XKB_KEY_XF86Display:
return DomKey::DISPLAY_SWAP;
case XKB_KEY_XF86Excel:
return DomKey::LAUNCH_SPREADSHEET;
case XKB_KEY_XF86LogOff:
return DomKey::LOG_OFF;
case XKB_KEY_XF86New:
return DomKey::NEW;
case XKB_KEY_XF86Open:
case XKB_KEY_SunOpen:
return DomKey::OPEN;
case XKB_KEY_XF86Paste:
case XKB_KEY_SunPaste:
return DomKey::PASTE;
case XKB_KEY_XF86Reply:
return DomKey::MAIL_REPLY;
case XKB_KEY_XF86Save:
return DomKey::SAVE;
case XKB_KEY_XF86Send:
return DomKey::MAIL_SEND;
case XKB_KEY_XF86Spell:
return DomKey::SPELL_CHECK;
case XKB_KEY_XF86SplitScreen:
return DomKey::SPLIT_SCREEN_TOGGLE;
case XKB_KEY_XF86Word:
case XKB_KEY_XF86OfficeHome:
return DomKey::LAUNCH_WORD_PROCESSOR;
case XKB_KEY_XF86ZoomIn:
return DomKey::ZOOM_IN;
case XKB_KEY_XF86ZoomOut:
return DomKey::ZOOM_OUT;
case XKB_KEY_XF86WebCam:
return DomKey::LAUNCH_WEB_CAM;
case XKB_KEY_XF86MailForward:
return DomKey::MAIL_FORWARD;
case XKB_KEY_XF86AudioForward:
return DomKey::MEDIA_FAST_FORWARD;
case XKB_KEY_XF86AudioRandomPlay:
return DomKey::RANDOM_TOGGLE;
case XKB_KEY_XF86Subtitle:
return DomKey::SUBTITLE;
case XKB_KEY_XF86Hibernate:
return DomKey::HIBERNATE;
case XKB_KEY_3270_EraseEOF:
return DomKey::ERASE_EOF;
case XKB_KEY_3270_Play:
return DomKey::PLAY;
case XKB_KEY_3270_ExSelect:
return DomKey::EX_SEL;
case XKB_KEY_3270_CursorSelect:
return DomKey::CR_SEL;
case XKB_KEY_ISO_Level3_Shift:
return DomKey::ALT_GRAPH;
case XKB_KEY_ISO_Level3_Latch:
return DomKey::ALT_GRAPH_LATCH;
case XKB_KEY_ISO_Level5_Shift:
return DomKey::SHIFT_LEVEL5;
case XKB_KEY_ISO_Next_Group:
return DomKey::GROUP_NEXT;
case XKB_KEY_ISO_Prev_Group:
return DomKey::GROUP_PREVIOUS;
case XKB_KEY_ISO_First_Group:
return DomKey::GROUP_FIRST;
case XKB_KEY_ISO_Last_Group:
return DomKey::GROUP_LAST;
case XKB_KEY_dead_grave:
// combining grave accent
return DomKey::DeadKeyFromCombiningCharacter(0x0300);
case XKB_KEY_dead_acute:
// combining acute accent
return DomKey::DeadKeyFromCombiningCharacter(0x0301);
case XKB_KEY_dead_circumflex:
// combining circumflex accent
return DomKey::DeadKeyFromCombiningCharacter(0x0302);
case XKB_KEY_dead_tilde:
// combining tilde
return DomKey::DeadKeyFromCombiningCharacter(0x0303);
case XKB_KEY_dead_macron:
// combining macron
return DomKey::DeadKeyFromCombiningCharacter(0x0304);
case XKB_KEY_dead_breve:
// combining breve
return DomKey::DeadKeyFromCombiningCharacter(0x0306);
case XKB_KEY_dead_abovedot:
// combining dot above
return DomKey::DeadKeyFromCombiningCharacter(0x0307);
case XKB_KEY_dead_diaeresis:
// combining diaeresis
return DomKey::DeadKeyFromCombiningCharacter(0x0308);
case XKB_KEY_dead_abovering:
// combining ring above
return DomKey::DeadKeyFromCombiningCharacter(0x030A);
case XKB_KEY_dead_doubleacute:
// combining double acute accent
return DomKey::DeadKeyFromCombiningCharacter(0x030B);
case XKB_KEY_dead_caron:
// combining caron
return DomKey::DeadKeyFromCombiningCharacter(0x030C);
case XKB_KEY_dead_cedilla:
// combining cedilla
return DomKey::DeadKeyFromCombiningCharacter(0x0327);
case XKB_KEY_dead_ogonek:
// combining ogonek
return DomKey::DeadKeyFromCombiningCharacter(0x0328);
case XKB_KEY_dead_iota:
// combining greek ypogegrammeni
return DomKey::DeadKeyFromCombiningCharacter(0x0345);
case XKB_KEY_dead_voiced_sound:
// combining voiced sound mark
return DomKey::DeadKeyFromCombiningCharacter(0x3099);
case XKB_KEY_dead_semivoiced_sound:
// combining semi-voiced sound mark
return DomKey::DeadKeyFromCombiningCharacter(0x309A);
case XKB_KEY_dead_belowdot:
// combining dot below
return DomKey::DeadKeyFromCombiningCharacter(0x0323);
case XKB_KEY_dead_hook:
// combining hook above
return DomKey::DeadKeyFromCombiningCharacter(0x0309);
case XKB_KEY_dead_horn:
// combining horn
return DomKey::DeadKeyFromCombiningCharacter(0x031B);
case XKB_KEY_dead_stroke:
// combining long solidus overlay
return DomKey::DeadKeyFromCombiningCharacter(0x0338);
case XKB_KEY_dead_abovecomma:
// combining comma above
return DomKey::DeadKeyFromCombiningCharacter(0x0313);
case XKB_KEY_dead_abovereversedcomma:
// combining reversed comma above
return DomKey::DeadKeyFromCombiningCharacter(0x0314);
case XKB_KEY_dead_doublegrave:
// combining double grave accent
return DomKey::DeadKeyFromCombiningCharacter(0x030F);
case XKB_KEY_dead_belowring:
// combining ring below
return DomKey::DeadKeyFromCombiningCharacter(0x0325);
case XKB_KEY_dead_belowmacron:
// combining macron below
return DomKey::DeadKeyFromCombiningCharacter(0x0331);
case XKB_KEY_dead_belowcircumflex:
// combining circumflex accent below
return DomKey::DeadKeyFromCombiningCharacter(0x032D);
case XKB_KEY_dead_belowtilde:
// combining tilde below
return DomKey::DeadKeyFromCombiningCharacter(0x0330);
case XKB_KEY_dead_belowbreve:
// combining breve below
return DomKey::DeadKeyFromCombiningCharacter(0x032E);
case XKB_KEY_dead_belowdiaeresis:
// combining diaeresis below
return DomKey::DeadKeyFromCombiningCharacter(0x0324);
case XKB_KEY_dead_invertedbreve:
// combining inverted breve
return DomKey::DeadKeyFromCombiningCharacter(0x0311);
case XKB_KEY_dead_belowcomma:
// combining comma below
return DomKey::DeadKeyFromCombiningCharacter(0x0326);
case XKB_KEY_dead_currency:
// currency sign
return DomKey::DeadKeyFromCombiningCharacter(0x00A4);
case XKB_KEY_dead_greek:
// greek question mark
return DomKey::DeadKeyFromCombiningCharacter(0x037E);
default:
if (keysym & kDeadKeyFlag) {
int32_t character = keysym & ~kDeadKeyFlag;
if ((character >= 0) && (character <= kUnicodeMax)) {
return DomKey::DeadKeyFromCombiningCharacter(character);
}
}
return DomKey::NONE;
}
}
DomKey XKeySymToDomKey(xkb_keysym_t keysym, base::char16 character) {
DomKey dom_key = NonPrintableXKeySymToDomKey(keysym);
if (dom_key != DomKey::NONE)
return dom_key;
return DomKey::FromCharacter(character);
}
} // namespace ui