OLD | NEW |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/events/keycodes/platform_key_map_win.h" | 5 #include "ui/events/keycodes/platform_key_map_win.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 return DomKey::ARROW_DOWN; | 132 return DomKey::ARROW_DOWN; |
133 case VKEY_INSERT: | 133 case VKEY_INSERT: |
134 return DomKey::INSERT; | 134 return DomKey::INSERT; |
135 case VKEY_DELETE: | 135 case VKEY_DELETE: |
136 return DomKey::DEL; | 136 return DomKey::DEL; |
137 default: | 137 default: |
138 return DomKey::NONE; | 138 return DomKey::NONE; |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
| 142 // This table must be sorted by |key_code| for binary search. |
| 143 const struct NonPrintableKeyEntry { |
| 144 KeyboardCode key_code; |
| 145 DomKey dom_key; |
| 146 } kNonPrintableKeyMap[] = { |
| 147 {VKEY_CANCEL, DomKey::CANCEL}, |
| 148 {VKEY_BACK, DomKey::BACKSPACE}, |
| 149 {VKEY_TAB, DomKey::TAB}, |
| 150 {VKEY_CLEAR, DomKey::CLEAR}, |
| 151 {VKEY_RETURN, DomKey::ENTER}, |
| 152 {VKEY_SHIFT, DomKey::SHIFT}, |
| 153 {VKEY_CONTROL, DomKey::CONTROL}, |
| 154 {VKEY_MENU, DomKey::ALT}, |
| 155 {VKEY_PAUSE, DomKey::PAUSE}, |
| 156 {VKEY_CAPITAL, DomKey::CAPS_LOCK}, |
| 157 // VKEY_KANA == VKEY_HANGUL |
| 158 {VKEY_JUNJA, DomKey::JUNJA_MODE}, |
| 159 {VKEY_FINAL, DomKey::FINAL_MODE}, |
| 160 // VKEY_HANJA == VKEY_KANJI |
| 161 {VKEY_ESCAPE, DomKey::ESCAPE}, |
| 162 {VKEY_CONVERT, DomKey::CONVERT}, |
| 163 {VKEY_NONCONVERT, DomKey::NON_CONVERT}, |
| 164 {VKEY_ACCEPT, DomKey::ACCEPT}, |
| 165 {VKEY_MODECHANGE, DomKey::MODE_CHANGE}, |
| 166 // VKEY_SPACE |
| 167 {VKEY_PRIOR, DomKey::PAGE_UP}, |
| 168 {VKEY_NEXT, DomKey::PAGE_DOWN}, |
| 169 {VKEY_END, DomKey::END}, |
| 170 {VKEY_HOME, DomKey::HOME}, |
| 171 {VKEY_LEFT, DomKey::ARROW_LEFT}, |
| 172 {VKEY_UP, DomKey::ARROW_UP}, |
| 173 {VKEY_RIGHT, DomKey::ARROW_RIGHT}, |
| 174 {VKEY_DOWN, DomKey::ARROW_DOWN}, |
| 175 {VKEY_SELECT, DomKey::SELECT}, |
| 176 {VKEY_PRINT, DomKey::PRINT}, |
| 177 {VKEY_EXECUTE, DomKey::EXECUTE}, |
| 178 {VKEY_SNAPSHOT, DomKey::PRINT_SCREEN}, |
| 179 {VKEY_INSERT, DomKey::INSERT}, |
| 180 {VKEY_DELETE, DomKey::DEL}, |
| 181 {VKEY_HELP, DomKey::HELP}, |
| 182 // VKEY_0..9 |
| 183 // VKEY_A..Z |
| 184 {VKEY_LWIN, DomKey::META}, |
| 185 // VKEY_COMMAND == VKEY_LWIN |
| 186 {VKEY_RWIN, DomKey::META}, |
| 187 {VKEY_APPS, DomKey::CONTEXT_MENU}, |
| 188 {VKEY_SLEEP, DomKey::STANDBY}, |
| 189 // VKEY_NUMPAD0..9 |
| 190 // VKEY_MULTIPLY, VKEY_ADD, VKEY_SEPARATOR, VKEY_SUBTRACT, VKEY_DECIMAL, |
| 191 // VKEY_DIVIDE |
| 192 {VKEY_F1, DomKey::F1}, |
| 193 {VKEY_F2, DomKey::F2}, |
| 194 {VKEY_F3, DomKey::F3}, |
| 195 {VKEY_F4, DomKey::F4}, |
| 196 {VKEY_F5, DomKey::F5}, |
| 197 {VKEY_F6, DomKey::F6}, |
| 198 {VKEY_F7, DomKey::F7}, |
| 199 {VKEY_F8, DomKey::F8}, |
| 200 {VKEY_F9, DomKey::F9}, |
| 201 {VKEY_F10, DomKey::F10}, |
| 202 {VKEY_F11, DomKey::F11}, |
| 203 {VKEY_F12, DomKey::F12}, |
| 204 {VKEY_F13, DomKey::F13}, |
| 205 {VKEY_F14, DomKey::F14}, |
| 206 {VKEY_F15, DomKey::F15}, |
| 207 {VKEY_F16, DomKey::F16}, |
| 208 {VKEY_F17, DomKey::F17}, |
| 209 {VKEY_F18, DomKey::F18}, |
| 210 {VKEY_F19, DomKey::F19}, |
| 211 {VKEY_F20, DomKey::F20}, |
| 212 {VKEY_F21, DomKey::F21}, |
| 213 {VKEY_F22, DomKey::F22}, |
| 214 {VKEY_F23, DomKey::F23}, |
| 215 {VKEY_F24, DomKey::F24}, |
| 216 {VKEY_NUMLOCK, DomKey::NUM_LOCK}, |
| 217 {VKEY_SCROLL, DomKey::SCROLL_LOCK}, |
| 218 {VKEY_LSHIFT, DomKey::SHIFT}, |
| 219 {VKEY_RSHIFT, DomKey::SHIFT}, |
| 220 {VKEY_LCONTROL, DomKey::CONTROL}, |
| 221 {VKEY_RCONTROL, DomKey::CONTROL}, |
| 222 {VKEY_LMENU, DomKey::ALT}, |
| 223 {VKEY_RMENU, DomKey::ALT}, |
| 224 {VKEY_BROWSER_BACK, DomKey::BROWSER_BACK}, |
| 225 {VKEY_BROWSER_FORWARD, DomKey::BROWSER_FORWARD}, |
| 226 {VKEY_BROWSER_REFRESH, DomKey::BROWSER_REFRESH}, |
| 227 {VKEY_BROWSER_STOP, DomKey::BROWSER_STOP}, |
| 228 {VKEY_BROWSER_SEARCH, DomKey::BROWSER_SEARCH}, |
| 229 {VKEY_BROWSER_FAVORITES, DomKey::BROWSER_FAVORITES}, |
| 230 {VKEY_BROWSER_HOME, DomKey::BROWSER_HOME}, |
| 231 {VKEY_VOLUME_MUTE, DomKey::AUDIO_VOLUME_MUTE}, |
| 232 {VKEY_VOLUME_DOWN, DomKey::AUDIO_VOLUME_DOWN}, |
| 233 {VKEY_VOLUME_UP, DomKey::AUDIO_VOLUME_UP}, |
| 234 {VKEY_MEDIA_NEXT_TRACK, DomKey::MEDIA_TRACK_NEXT}, |
| 235 {VKEY_MEDIA_PREV_TRACK, DomKey::MEDIA_TRACK_PREVIOUS}, |
| 236 {VKEY_MEDIA_STOP, DomKey::MEDIA_STOP}, |
| 237 {VKEY_MEDIA_PLAY_PAUSE, DomKey::MEDIA_PLAY_PAUSE}, |
| 238 {VKEY_MEDIA_LAUNCH_MAIL, DomKey::LAUNCH_MAIL}, |
| 239 {VKEY_MEDIA_LAUNCH_MEDIA_SELECT, DomKey::LAUNCH_MEDIA_PLAYER}, |
| 240 // TODO(chongz): Actually we don't know whether it's mapped to launch |
| 241 // computer/calculator or not, better use a generic DomKey string. |
| 242 // https://crbug.com/612743 |
| 243 {VKEY_MEDIA_LAUNCH_APP1, DomKey::LAUNCH_MY_COMPUTER}, |
| 244 {VKEY_MEDIA_LAUNCH_APP2, DomKey::LAUNCH_CALCULATOR}, |
| 245 // VKEY_OEM_1..8, 102, PLUS, COMMA, MINUS, PERIOD |
| 246 {VKEY_ALTGR, DomKey::ALT_GRAPH}, |
| 247 {VKEY_PROCESSKEY, DomKey::PROCESS}, |
| 248 // VKEY_PACKET - Used to pass Unicode char, considered as printable key. |
| 249 |
| 250 // TODO(chongz): Handle Japanese keyboard layout keys 0xF0..0xF5. |
| 251 // https://crbug.com/612694 |
| 252 {VKEY_ATTN, DomKey::ATTN}, |
| 253 {VKEY_CRSEL, DomKey::CR_SEL}, |
| 254 {VKEY_EXSEL, DomKey::EX_SEL}, |
| 255 {VKEY_EREOF, DomKey::ERASE_EOF}, |
| 256 {VKEY_PLAY, DomKey::PLAY}, |
| 257 {VKEY_ZOOM, DomKey::ZOOM_TOGGLE}, |
| 258 // TODO(chongz): Handle VKEY_NONAME, VKEY_PA1. |
| 259 // https://crbug.com/616910 |
| 260 {VKEY_OEM_CLEAR, DomKey::CLEAR}, |
| 261 }; |
| 262 |
| 263 DomKey NonPrintableKeyboardCodeToDomKey(KeyboardCode key_code) { |
| 264 const NonPrintableKeyEntry* result = std::lower_bound( |
| 265 std::begin(kNonPrintableKeyMap), std::end(kNonPrintableKeyMap), key_code, |
| 266 [](const NonPrintableKeyEntry& entry, KeyboardCode needle) { |
| 267 return entry.key_code < needle; |
| 268 }); |
| 269 if (result != std::end(kNonPrintableKeyMap) && result->key_code == key_code) |
| 270 return result->dom_key; |
| 271 return DomKey::NONE; |
| 272 } |
| 273 |
142 void CleanupKeyMapTls(void* data) { | 274 void CleanupKeyMapTls(void* data) { |
143 PlatformKeyMap* key_map = reinterpret_cast<PlatformKeyMap*>(data); | 275 PlatformKeyMap* key_map = reinterpret_cast<PlatformKeyMap*>(data); |
144 delete key_map; | 276 delete key_map; |
145 } | 277 } |
146 | 278 |
147 struct PlatformKeyMapInstanceTlsTraits | 279 struct PlatformKeyMapInstanceTlsTraits |
148 : public base::DefaultLazyInstanceTraits<base::ThreadLocalStorage::Slot> { | 280 : public base::DefaultLazyInstanceTraits<base::ThreadLocalStorage::Slot> { |
149 static base::ThreadLocalStorage::Slot* New(void* instance) { | 281 static base::ThreadLocalStorage::Slot* New(void* instance) { |
150 // Use placement new to initialize our instance in our preallocated space. | 282 // Use placement new to initialize our instance in our preallocated space. |
151 // TODO(chongz): Use std::default_delete instead of providing own function. | 283 // TODO(chongz): Use std::default_delete instead of providing own function. |
(...skipping 11 matching lines...) Expand all Loading... |
163 | 295 |
164 PlatformKeyMap::PlatformKeyMap(HKL layout) { | 296 PlatformKeyMap::PlatformKeyMap(HKL layout) { |
165 UpdateLayout(layout); | 297 UpdateLayout(layout); |
166 } | 298 } |
167 | 299 |
168 PlatformKeyMap::~PlatformKeyMap() {} | 300 PlatformKeyMap::~PlatformKeyMap() {} |
169 | 301 |
170 DomKey PlatformKeyMap::DomKeyFromNativeImpl(DomCode code, | 302 DomKey PlatformKeyMap::DomKeyFromNativeImpl(DomCode code, |
171 KeyboardCode key_code, | 303 KeyboardCode key_code, |
172 int flags) const { | 304 int flags) const { |
| 305 DomKey key = NonPrintableKeyboardCodeToDomKey(key_code); |
| 306 if (key != DomKey::NONE) |
| 307 return key; |
| 308 |
| 309 // TODO(chongz): Handle VKEY_KANA/VKEY_HANGUL, VKEY_HANJA/VKEY_KANJI based on |
| 310 // layout. |
| 311 // https://crbug.com/612736 |
| 312 |
173 if (KeycodeConverter::DomCodeToLocation(code) == DomKeyLocation::NUMPAD) { | 313 if (KeycodeConverter::DomCodeToLocation(code) == DomKeyLocation::NUMPAD) { |
174 // Derived the DOM Key value from |key_code| instead of |code|, to address | 314 // Derived the DOM Key value from |key_code| instead of |code|, to address |
175 // Windows Numlock/Shift interaction - see crbug.com/594552. | 315 // Windows Numlock/Shift interaction - see crbug.com/594552. |
176 return NumPadKeyCodeToDomKey(key_code); | 316 return NumPadKeyCodeToDomKey(key_code); |
177 } | 317 } |
178 | 318 |
179 const int flags_to_try[] = { | 319 const int flags_to_try[] = { |
180 // Trying to match Firefox's behavior and UIEvents DomKey guidelines. | 320 // Trying to match Firefox's behavior and UIEvents DomKey guidelines. |
181 // If the combination doesn't produce a printable character, the key value | 321 // If the combination doesn't produce a printable character, the key value |
182 // should be the key with no modifiers except for Shift and AltGr. | 322 // should be the key with no modifiers except for Shift and AltGr. |
183 // See https://w3c.github.io/uievents/#keys-guidelines | 323 // See https://w3c.github.io/uievents/#keys-guidelines |
184 flags, | 324 flags, |
185 flags & (EF_SHIFT_DOWN | EF_ALTGR_DOWN | EF_CAPS_LOCK_ON), | 325 flags & (EF_SHIFT_DOWN | EF_ALTGR_DOWN | EF_CAPS_LOCK_ON), |
186 flags & (EF_SHIFT_DOWN | EF_CAPS_LOCK_ON), | 326 flags & (EF_SHIFT_DOWN | EF_CAPS_LOCK_ON), |
187 EF_NONE, | 327 EF_NONE, |
188 }; | 328 }; |
189 | 329 |
190 DomKey key = DomKey::NONE; | |
191 for (auto try_flags : flags_to_try) { | 330 for (auto try_flags : flags_to_try) { |
192 const auto& it = code_to_key_.find(std::make_pair(static_cast<int>(code), | 331 const auto& it = code_to_key_.find(std::make_pair(static_cast<int>(code), |
193 try_flags)); | 332 try_flags)); |
194 if (it != code_to_key_.end()) { | 333 if (it != code_to_key_.end()) { |
195 key = it->second; | 334 key = it->second; |
196 if (key != DomKey::NONE) | 335 if (key != DomKey::NONE) |
197 break; | 336 break; |
198 } | 337 } |
199 } | 338 } |
200 return key; | 339 return key; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 } | 411 } |
273 } else { | 412 } else { |
274 // TODO(chongz): Handle rv <= -2 and rv >= 2. | 413 // TODO(chongz): Handle rv <= -2 and rv >= 2. |
275 } | 414 } |
276 } | 415 } |
277 } | 416 } |
278 ::SetKeyboardState(keyboard_state_to_restore); | 417 ::SetKeyboardState(keyboard_state_to_restore); |
279 } | 418 } |
280 | 419 |
281 } // namespace ui | 420 } // namespace ui |
OLD | NEW |