1/*
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
4 * Copyright (C) 2007 Holger Hans Peter Freyther
5 * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "PlatformKeyboardEvent.h"
32
33#include "GtkUtilities.h"
34#include "GtkVersioning.h"
35#include "NotImplemented.h"
36#include "TextEncoding.h"
37#include "WindowsKeyboardCodes.h"
38#include <gdk/gdk.h>
39#include <gdk/gdkkeysyms.h>
40#include <wtf/HexNumber.h>
41#include <wtf/glib/GUniquePtr.h>
42
43namespace WebCore {
44
45// FIXME: This is incomplete. We should change this to mirror
46// more like what Firefox does, and generate these switch statements
47// at build time.
48// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
49String PlatformKeyboardEvent::keyValueForGdkKeyCode(unsigned keyCode)
50{
51 switch (keyCode) {
52 // Modifier keys.
53 case GDK_KEY_Alt_L:
54 case GDK_KEY_Alt_R:
55 return "Alt"_s;
56 // Firefox uses GDK_KEY_Mode_switch for AltGraph as well.
57 case GDK_KEY_ISO_Level3_Shift:
58 case GDK_KEY_ISO_Level3_Latch:
59 case GDK_KEY_ISO_Level3_Lock:
60 case GDK_KEY_ISO_Level5_Shift:
61 case GDK_KEY_ISO_Level5_Latch:
62 case GDK_KEY_ISO_Level5_Lock:
63 return "AltGraph"_s;
64 case GDK_KEY_Caps_Lock:
65 return "CapsLock"_s;
66 case GDK_KEY_Control_L:
67 case GDK_KEY_Control_R:
68 return "Control"_s;
69 // Fn: This is typically a hardware key that does not generate a separate code.
70 // FnLock.
71 case GDK_KEY_Hyper_L:
72 case GDK_KEY_Hyper_R:
73 return "Hyper"_s;
74 case GDK_KEY_Meta_L:
75 case GDK_KEY_Meta_R:
76 return "Meta"_s;
77 case GDK_KEY_Num_Lock:
78 return "NumLock"_s;
79 case GDK_KEY_Scroll_Lock:
80 return "ScrollLock"_s;
81 case GDK_KEY_Shift_L:
82 case GDK_KEY_Shift_R:
83 return "Shift"_s;
84 case GDK_KEY_Super_L:
85 case GDK_KEY_Super_R:
86 return "Super"_s;
87 // Symbol.
88 // SymbolLock.
89
90 // Whitespace keys.
91 case GDK_KEY_Return:
92 case GDK_KEY_KP_Enter:
93 case GDK_KEY_ISO_Enter:
94 case GDK_KEY_3270_Enter:
95 return "Enter"_s;
96 case GDK_KEY_Tab:
97 case GDK_KEY_KP_Tab:
98 return "Tab"_s;
99
100 // Navigation keys.
101 case GDK_KEY_Down:
102 case GDK_KEY_KP_Down:
103 return "ArrowDown"_s;
104 case GDK_KEY_Left:
105 case GDK_KEY_KP_Left:
106 return "ArrowLeft"_s;
107 case GDK_KEY_Right:
108 case GDK_KEY_KP_Right:
109 return "ArrowRight"_s;
110 case GDK_KEY_Up:
111 case GDK_KEY_KP_Up:
112 return "ArrowUp"_s;
113 case GDK_KEY_End:
114 case GDK_KEY_KP_End:
115 return "End"_s;
116 case GDK_KEY_Home:
117 case GDK_KEY_KP_Home:
118 return "Home"_s;
119 case GDK_KEY_Page_Down:
120 case GDK_KEY_KP_Page_Down:
121 return "PageDown"_s;
122 case GDK_KEY_Page_Up:
123 case GDK_KEY_KP_Page_Up:
124 return "PageUp"_s;
125
126 // Editing keys.
127 case GDK_KEY_BackSpace:
128 return "Backspace"_s;
129 case GDK_KEY_Clear:
130 return "Clear"_s;
131 case GDK_KEY_Copy:
132 return "Copy"_s;
133 case GDK_KEY_3270_CursorSelect:
134 return "CrSel"_s;
135 case GDK_KEY_Cut:
136 return "Cut"_s;
137 case GDK_KEY_Delete:
138 case GDK_KEY_KP_Delete:
139 return "Delete"_s;
140 case GDK_KEY_3270_EraseEOF:
141 return "EraseEof"_s;
142 case GDK_KEY_3270_ExSelect:
143 return "ExSel"_s;
144 case GDK_KEY_Insert:
145 case GDK_KEY_KP_Insert:
146 return "Insert"_s;
147 case GDK_KEY_Paste:
148 return "Paste"_s;
149 case GDK_KEY_Redo:
150 return "Redo"_s;
151 case GDK_KEY_Undo:
152 return "Undo"_s;
153
154 // UI keys.
155 // Accept.
156 // Again.
157 case GDK_KEY_3270_Attn:
158 return "Attn"_s;
159 case GDK_KEY_Cancel:
160 return "Cancel"_s;
161 case GDK_KEY_Menu:
162 return "ContextMenu"_s;
163 case GDK_KEY_Escape:
164 return "Escape"_s;
165 case GDK_KEY_Execute:
166 return "Execute"_s;
167 case GDK_KEY_Find:
168 return "Find"_s;
169 case GDK_KEY_Help:
170 return "Help"_s;
171 case GDK_KEY_Pause:
172 case GDK_KEY_Break:
173 return "Pause"_s;
174 case GDK_KEY_3270_Play:
175 return "Play"_s;
176 // Props.
177 case GDK_KEY_Select:
178 return "Select"_s;
179 case GDK_KEY_ZoomIn:
180 return "ZoomIn"_s;
181 case GDK_KEY_ZoomOut:
182 return "ZoomOut"_s;
183
184 // Device keys.
185 case GDK_KEY_MonBrightnessDown:
186 return "BrightnessDown"_s;
187 case GDK_KEY_MonBrightnessUp:
188 return "BrightnessUp"_s;
189 case GDK_KEY_Eject:
190 return "Eject"_s;
191 case GDK_KEY_LogOff:
192 return "LogOff"_s;
193 // Power.
194 case GDK_KEY_PowerDown:
195 case GDK_KEY_PowerOff:
196 return "PowerOff"_s;
197 case GDK_KEY_3270_PrintScreen:
198 case GDK_KEY_Print:
199 case GDK_KEY_Sys_Req:
200 return "PrintScreen"_s;
201 case GDK_KEY_Hibernate:
202 return "Hibernate"_s;
203 case GDK_KEY_Standby:
204 case GDK_KEY_Suspend:
205 case GDK_KEY_Sleep:
206 return "Standby"_s;
207 case GDK_KEY_WakeUp:
208 return "WakeUp"_s;
209
210 // IME keys.
211 case GDK_KEY_MultipleCandidate:
212 return "AllCandidates"_s;
213 case GDK_KEY_Eisu_Shift:
214 case GDK_KEY_Eisu_toggle:
215 return "Alphanumeric"_s;
216 case GDK_KEY_Codeinput:
217 return "CodeInput"_s;
218 case GDK_KEY_Multi_key:
219 return "Compose"_s;
220 case GDK_KEY_Henkan:
221 return "Convert"_s;
222 case GDK_KEY_dead_grave:
223 case GDK_KEY_dead_acute:
224 case GDK_KEY_dead_circumflex:
225 case GDK_KEY_dead_tilde:
226 case GDK_KEY_dead_macron:
227 case GDK_KEY_dead_breve:
228 case GDK_KEY_dead_abovedot:
229 case GDK_KEY_dead_diaeresis:
230 case GDK_KEY_dead_abovering:
231 case GDK_KEY_dead_doubleacute:
232 case GDK_KEY_dead_caron:
233 case GDK_KEY_dead_cedilla:
234 case GDK_KEY_dead_ogonek:
235 case GDK_KEY_dead_iota:
236 case GDK_KEY_dead_voiced_sound:
237 case GDK_KEY_dead_semivoiced_sound:
238 case GDK_KEY_dead_belowdot:
239 case GDK_KEY_dead_hook:
240 case GDK_KEY_dead_horn:
241 case GDK_KEY_dead_stroke:
242 case GDK_KEY_dead_abovecomma:
243 case GDK_KEY_dead_abovereversedcomma:
244 case GDK_KEY_dead_doublegrave:
245 case GDK_KEY_dead_belowring:
246 case GDK_KEY_dead_belowmacron:
247 case GDK_KEY_dead_belowcircumflex:
248 case GDK_KEY_dead_belowtilde:
249 case GDK_KEY_dead_belowbreve:
250 case GDK_KEY_dead_belowdiaeresis:
251 case GDK_KEY_dead_invertedbreve:
252 case GDK_KEY_dead_belowcomma:
253 case GDK_KEY_dead_currency:
254 case GDK_KEY_dead_a:
255 case GDK_KEY_dead_A:
256 case GDK_KEY_dead_e:
257 case GDK_KEY_dead_E:
258 case GDK_KEY_dead_i:
259 case GDK_KEY_dead_I:
260 case GDK_KEY_dead_o:
261 case GDK_KEY_dead_O:
262 case GDK_KEY_dead_u:
263 case GDK_KEY_dead_U:
264 case GDK_KEY_dead_small_schwa:
265 case GDK_KEY_dead_capital_schwa:
266 return "Dead"_s;
267 // FinalMode
268 case GDK_KEY_ISO_First_Group:
269 return "GroupFirst"_s;
270 case GDK_KEY_ISO_Last_Group:
271 return "GroupLast"_s;
272 case GDK_KEY_ISO_Next_Group:
273 return "GroupNext"_s;
274 case GDK_KEY_ISO_Prev_Group:
275 return "GroupPrevious"_s;
276 case GDK_KEY_Mode_switch:
277 return "ModeChange"_s;
278 // NextCandidate.
279 case GDK_KEY_Muhenkan:
280 return "NonConvert"_s;
281 case GDK_KEY_PreviousCandidate:
282 return "PreviousCandidate"_s;
283 // Process.
284 case GDK_KEY_SingleCandidate:
285 return "SingleCandidate"_s;
286
287 // Korean and Japanese keys.
288 case GDK_KEY_Hangul:
289 return "HangulMode"_s;
290 case GDK_KEY_Hangul_Hanja:
291 return "HanjaMode"_s;
292 case GDK_KEY_Hangul_Jeonja:
293 return "JunjaMode"_s;
294 case GDK_KEY_Hankaku:
295 return "Hankaku"_s;
296 case GDK_KEY_Hiragana:
297 return "Hiragana"_s;
298 case GDK_KEY_Hiragana_Katakana:
299 return "HiraganaKatakana"_s;
300 case GDK_KEY_Kana_Lock:
301 case GDK_KEY_Kana_Shift:
302 return "KanaMode"_s;
303 case GDK_KEY_Kanji:
304 return "KanjiMode"_s;
305 case GDK_KEY_Katakana:
306 return "Katakana"_s;
307 case GDK_KEY_Romaji:
308 return "Romaji"_s;
309 case GDK_KEY_Zenkaku:
310 return "Zenkaku"_s;
311 case GDK_KEY_Zenkaku_Hankaku:
312 return "ZenkakuHanaku"_s;
313
314 // Application Keys
315 case GDK_KEY_AudioMedia:
316 return "LaunchMediaPlayer"_s;
317
318 // Browser Keys
319 case GDK_KEY_Back:
320 return "BrowserBack"_s;
321 case GDK_KEY_Favorites:
322 return "BrowserFavorites"_s;
323 case GDK_KEY_Forward:
324 return "BrowserForward"_s;
325 case GDK_KEY_HomePage:
326 return "BrowserHome"_s;
327 case GDK_KEY_Refresh:
328 return "BrowserRefresh"_s;
329 case GDK_KEY_Search:
330 return "BrowserSearch"_s;
331 case GDK_KEY_Stop:
332 return "BrowserStop"_s;
333
334 // ChannelDown.
335 // ChannelUp.
336 case GDK_KEY_Close:
337 return "Close"_s;
338 case GDK_KEY_MailForward:
339 return "MailForward"_s;
340 case GDK_KEY_Reply:
341 return "MailReply"_s;
342 case GDK_KEY_Send:
343 return "MailSend"_s;
344 case GDK_KEY_AudioForward:
345 return "MediaFastForward"_s;
346 case GDK_KEY_AudioPause:
347 return "MediaPause"_s;
348 case GDK_KEY_AudioPlay:
349 return "MediaPlay"_s;
350 // MediaPlayPause
351 case GDK_KEY_AudioRecord:
352 return "MediaRecord"_s;
353 case GDK_KEY_AudioRewind:
354 return "MediaRewind"_s;
355 case GDK_KEY_AudioStop:
356 return "MediaStop"_s;
357 case GDK_KEY_AudioNext:
358 return "MediaTrackNext"_s;
359 case GDK_KEY_AudioPrev:
360 return "MediaTrackPrevious"_s;
361 case GDK_KEY_New:
362 return "New"_s;
363 case GDK_KEY_Open:
364 return "Open"_s;
365 case GDK_KEY_AudioLowerVolume:
366 return "AudioVolumeDown"_s;
367 case GDK_KEY_AudioRaiseVolume:
368 return "AudioVolumeUp"_s;
369 case GDK_KEY_AudioMute:
370 return "AudioVolumeMute"_s;
371
372 // Media Controller Keys
373 case GDK_KEY_Red:
374 return "ColorF0Red"_s;
375 case GDK_KEY_Green:
376 return "ColorF1Green"_s;
377 case GDK_KEY_Yellow:
378 return "ColorF2Yellow"_s;
379 case GDK_KEY_Blue:
380 return "ColorF3Blue"_s;
381 case GDK_KEY_Display:
382 return "DisplaySwap"_s;
383 case GDK_KEY_Video:
384 return "OnDemand"_s;
385 case GDK_KEY_Subtitle:
386 return "Subtitle"_s;
387
388 // Print.
389 case GDK_KEY_Save:
390 return "Save"_s;
391 case GDK_KEY_Spell:
392 return "SpellCheck"_s;
393
394 // Function keys.
395 case GDK_KEY_F1:
396 return "F1"_s;
397 case GDK_KEY_F2:
398 return "F2"_s;
399 case GDK_KEY_F3:
400 return "F3"_s;
401 case GDK_KEY_F4:
402 return "F4"_s;
403 case GDK_KEY_F5:
404 return "F5"_s;
405 case GDK_KEY_F6:
406 return "F6"_s;
407 case GDK_KEY_F7:
408 return "F7"_s;
409 case GDK_KEY_F8:
410 return "F8"_s;
411 case GDK_KEY_F9:
412 return "F9"_s;
413 case GDK_KEY_F10:
414 return "F10"_s;
415 case GDK_KEY_F11:
416 return "F11"_s;
417 case GDK_KEY_F12:
418 return "F12"_s;
419 case GDK_KEY_F13:
420 return "F13"_s;
421 case GDK_KEY_F14:
422 return "F14"_s;
423 case GDK_KEY_F15:
424 return "F15"_s;
425 case GDK_KEY_F16:
426 return "F16"_s;
427 case GDK_KEY_F17:
428 return "F17"_s;
429 case GDK_KEY_F18:
430 return "F18"_s;
431 case GDK_KEY_F19:
432 return "F19"_s;
433 case GDK_KEY_F20:
434 return "F20"_s;
435
436 default: {
437 guint32 unicodeCharacter = gdk_keyval_to_unicode(keyCode);
438 if (unicodeCharacter) {
439 // UTF-8 will use up to 6 bytes.
440 char utf8[7] = { 0 };
441 g_unichar_to_utf8(unicodeCharacter, utf8);
442 return String::fromUTF8(utf8);
443 }
444 return "Unidentified"_s;
445 }
446 }
447}
448
449// FIXME: This is incomplete. We should change this to mirror
450// more like what Firefox does, and generate these switch statements
451// at build time.
452// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
453String PlatformKeyboardEvent::keyCodeForHardwareKeyCode(unsigned keyCode)
454{
455 switch (keyCode) {
456 case 0x0009:
457 return "Escape"_s;
458 case 0x000A:
459 return "Digit1"_s;
460 case 0x000B:
461 return "Digit2"_s;
462 case 0x000C:
463 return "Digit3"_s;
464 case 0x000D:
465 return "Digit4"_s;
466 case 0x000E:
467 return "Digit5"_s;
468 case 0x000F:
469 return "Digit6"_s;
470 case 0x0010:
471 return "Digit7"_s;
472 case 0x0011:
473 return "Digit8"_s;
474 case 0x0012:
475 return "Digit9"_s;
476 case 0x0013:
477 return "Digit0"_s;
478 case 0x0014:
479 return "Minus"_s;
480 case 0x0015:
481 return "Equal"_s;
482 case 0x0016:
483 return "Backspace"_s;
484 case 0x0017:
485 return "Tab"_s;
486 case 0x0018:
487 return "KeyQ"_s;
488 case 0x0019:
489 return "KeyW"_s;
490 case 0x001A:
491 return "KeyE"_s;
492 case 0x001B:
493 return "KeyR"_s;
494 case 0x001C:
495 return "KeyT"_s;
496 case 0x001D:
497 return "KeyY"_s;
498 case 0x001E:
499 return "KeyU"_s;
500 case 0x001F:
501 return "KeyI"_s;
502 case 0x0020:
503 return "KeyO"_s;
504 case 0x0021:
505 return "KeyP"_s;
506 case 0x0022:
507 return "BracketLeft"_s;
508 case 0x0023:
509 return "BracketRight"_s;
510 case 0x0024:
511 return "Enter"_s;
512 case 0x0025:
513 return "ControlLeft"_s;
514 case 0x0026:
515 return "KeyA"_s;
516 case 0x0027:
517 return "KeyS"_s;
518 case 0x0028:
519 return "KeyD"_s;
520 case 0x0029:
521 return "KeyF"_s;
522 case 0x002A:
523 return "KeyG"_s;
524 case 0x002B:
525 return "KeyH"_s;
526 case 0x002C:
527 return "KeyJ"_s;
528 case 0x002D:
529 return "KeyK"_s;
530 case 0x002E:
531 return "KeyL"_s;
532 case 0x002F:
533 return "Semicolon"_s;
534 case 0x0030:
535 return "Quote"_s;
536 case 0x0031:
537 return "Backquote"_s;
538 case 0x0032:
539 return "ShiftLeft"_s;
540 case 0x0033:
541 return "Backslash"_s;
542 case 0x0034:
543 return "KeyZ"_s;
544 case 0x0035:
545 return "KeyX"_s;
546 case 0x0036:
547 return "KeyC"_s;
548 case 0x0037:
549 return "KeyV"_s;
550 case 0x0038:
551 return "KeyB"_s;
552 case 0x0039:
553 return "KeyN"_s;
554 case 0x003A:
555 return "KeyM"_s;
556 case 0x003B:
557 return "Comma"_s;
558 case 0x003C:
559 return "Period"_s;
560 case 0x003D:
561 return "Slash"_s;
562 case 0x003E:
563 return "ShiftRight"_s;
564 case 0x003F:
565 return "NumpadMultiply"_s;
566 case 0x0040:
567 return "AltLeft"_s;
568 case 0x0041:
569 return "Space"_s;
570 case 0x0042:
571 return "CapsLock"_s;
572 case 0x0043:
573 return "F1"_s;
574 case 0x0044:
575 return "F2"_s;
576 case 0x0045:
577 return "F3"_s;
578 case 0x0046:
579 return "F4"_s;
580 case 0x0047:
581 return "F5"_s;
582 case 0x0048:
583 return "F6"_s;
584 case 0x0049:
585 return "F7"_s;
586 case 0x004A:
587 return "F8"_s;
588 case 0x004B:
589 return "F9"_s;
590 case 0x004C:
591 return "F10"_s;
592 case 0x004D:
593 return "NumLock"_s;
594 case 0x004E:
595 return "ScrollLock"_s;
596 case 0x004F:
597 return "Numpad7"_s;
598 case 0x0050:
599 return "Numpad8"_s;
600 case 0x0051:
601 return "Numpad9"_s;
602 case 0x0052:
603 return "NumpadSubtract"_s;
604 case 0x0053:
605 return "Numpad4"_s;
606 case 0x0054:
607 return "Numpad5"_s;
608 case 0x0055:
609 return "Numpad6"_s;
610 case 0x0056:
611 return "NumpadAdd"_s;
612 case 0x0057:
613 return "Numpad1"_s;
614 case 0x0058:
615 return "Numpad2"_s;
616 case 0x0059:
617 return "Numpad3"_s;
618 case 0x005A:
619 return "Numpad0"_s;
620 case 0x005B:
621 return "NumpadDecimal"_s;
622 case 0x005E:
623 return "IntlBackslash"_s;
624 case 0x005F:
625 return "F11"_s;
626 case 0x0060:
627 return "F12"_s;
628 case 0x0061:
629 return "IntlRo"_s;
630 case 0x0064:
631 return "Convert"_s;
632 case 0x0065:
633 return "KanaMode"_s;
634 case 0x0066:
635 return "NonConvert"_s;
636 case 0x0068:
637 return "NumpadEnter"_s;
638 case 0x0069:
639 return "ControlRight"_s;
640 case 0x006A:
641 return "NumpadDivide"_s;
642 case 0x006B:
643 return "PrintScreen"_s;
644 case 0x006C:
645 return "AltRight"_s;
646 case 0x006E:
647 return "Home"_s;
648 case 0x006F:
649 return "ArrowUp"_s;
650 case 0x0070:
651 return "PageUp"_s;
652 case 0x0071:
653 return "ArrowLeft"_s;
654 case 0x0072:
655 return "ArrowRight"_s;
656 case 0x0073:
657 return "End"_s;
658 case 0x0074:
659 return "ArrowDown"_s;
660 case 0x0075:
661 return "PageDown"_s;
662 case 0x0076:
663 return "Insert"_s;
664 case 0x0077:
665 return "Delete"_s;
666 case 0x0079:
667 return "AudioVolumeMute"_s;
668 case 0x007A:
669 return "AudioVolumeDown"_s;
670 case 0x007B:
671 return "AudioVolumeUp"_s;
672 case 0x007D:
673 return "NumpadEqual"_s;
674 case 0x007F:
675 return "Pause"_s;
676 case 0x0081:
677 return "NumpadComma"_s;
678 case 0x0082:
679 return "Lang1"_s;
680 case 0x0083:
681 return "Lang2"_s;
682 case 0x0084:
683 return "IntlYen"_s;
684 case 0x0085:
685 return "OSLeft"_s;
686 case 0x0086:
687 return "OSRight"_s;
688 case 0x0087:
689 return "ContextMenu"_s;
690 case 0x0088:
691 return "BrowserStop"_s;
692 case 0x0089:
693 return "Again"_s;
694 case 0x008A:
695 return "Props"_s;
696 case 0x008B:
697 return "Undo"_s;
698 case 0x008C:
699 return "Select"_s;
700 case 0x008D:
701 return "Copy"_s;
702 case 0x008E:
703 return "Open"_s;
704 case 0x008F:
705 return "Paste"_s;
706 case 0x0090:
707 return "Find"_s;
708 case 0x0091:
709 return "Cut"_s;
710 case 0x0092:
711 return "Help"_s;
712 case 0x0094:
713 return "LaunchApp2"_s;
714 case 0x0097:
715 return "WakeUp"_s;
716 case 0x0098:
717 return "LaunchApp1"_s;
718 case 0x00A3:
719 return "LaunchMail"_s;
720 case 0x00A4:
721 return "BrowserFavorites"_s;
722 case 0x00A6:
723 return "BrowserBack"_s;
724 case 0x00A7:
725 return "BrowserForward"_s;
726 case 0x00A9:
727 return "Eject"_s;
728 case 0x00AB:
729 return "MediaTrackNext"_s;
730 case 0x00AC:
731 return "MediaPlayPause"_s;
732 case 0x00AD:
733 return "MediaTrackPrevious"_s;
734 case 0x00AE:
735 return "MediaStop"_s;
736 case 0x00B3:
737 return "LaunchMediaPlayer"_s;
738 case 0x00B4:
739 return "BrowserHome"_s;
740 case 0x00B5:
741 return "BrowserRefresh"_s;
742 case 0x00BF:
743 return "F13"_s;
744 case 0x00C0:
745 return "F14"_s;
746 case 0x00C1:
747 return "F15"_s;
748 case 0x00C2:
749 return "F16"_s;
750 case 0x00C3:
751 return "F17"_s;
752 case 0x00C4:
753 return "F18"_s;
754 case 0x00C5:
755 return "F19"_s;
756 case 0x00C6:
757 return "F20"_s;
758 case 0x00C7:
759 return "F21"_s;
760 case 0x00C8:
761 return "F22"_s;
762 case 0x00C9:
763 return "F23"_s;
764 case 0x00CA:
765 return "F24"_s;
766 case 0x00E1:
767 return "BrowserSearch"_s;
768 default:
769 return "Unidentified"_s;
770 }
771}
772
773// FIXME: This is incomplete. We should change this to mirror
774// more like what Firefox does, and generate these switch statements
775// at build time.
776String PlatformKeyboardEvent::keyIdentifierForGdkKeyCode(unsigned keyCode)
777{
778 switch (keyCode) {
779 case GDK_Menu:
780 case GDK_Alt_L:
781 case GDK_Alt_R:
782 return "Alt";
783 case GDK_Clear:
784 return "Clear";
785 case GDK_Down:
786 return "Down";
787 // "End"
788 case GDK_End:
789 return "End";
790 // "Enter"
791 case GDK_ISO_Enter:
792 case GDK_KP_Enter:
793 case GDK_Return:
794 return "Enter";
795 case GDK_Execute:
796 return "Execute";
797 case GDK_F1:
798 return "F1";
799 case GDK_F2:
800 return "F2";
801 case GDK_F3:
802 return "F3";
803 case GDK_F4:
804 return "F4";
805 case GDK_F5:
806 return "F5";
807 case GDK_F6:
808 return "F6";
809 case GDK_F7:
810 return "F7";
811 case GDK_F8:
812 return "F8";
813 case GDK_F9:
814 return "F9";
815 case GDK_F10:
816 return "F10";
817 case GDK_F11:
818 return "F11";
819 case GDK_F12:
820 return "F12";
821 case GDK_F13:
822 return "F13";
823 case GDK_F14:
824 return "F14";
825 case GDK_F15:
826 return "F15";
827 case GDK_F16:
828 return "F16";
829 case GDK_F17:
830 return "F17";
831 case GDK_F18:
832 return "F18";
833 case GDK_F19:
834 return "F19";
835 case GDK_F20:
836 return "F20";
837 case GDK_F21:
838 return "F21";
839 case GDK_F22:
840 return "F22";
841 case GDK_F23:
842 return "F23";
843 case GDK_F24:
844 return "F24";
845 case GDK_Help:
846 return "Help";
847 case GDK_Home:
848 return "Home";
849 case GDK_Insert:
850 return "Insert";
851 case GDK_Left:
852 return "Left";
853 case GDK_Page_Down:
854 return "PageDown";
855 case GDK_Page_Up:
856 return "PageUp";
857 case GDK_Pause:
858 return "Pause";
859 case GDK_3270_PrintScreen:
860 case GDK_Print:
861 return "PrintScreen";
862 case GDK_Right:
863 return "Right";
864 case GDK_Select:
865 return "Select";
866 case GDK_Up:
867 return "Up";
868 // Standard says that DEL becomes U+007F.
869 case GDK_Delete:
870 return "U+007F";
871 case GDK_BackSpace:
872 return "U+0008";
873 case GDK_ISO_Left_Tab:
874 case GDK_3270_BackTab:
875 case GDK_Tab:
876 return "U+0009";
877 default:
878 return makeString("U+", hex(gdk_keyval_to_unicode(gdk_keyval_to_upper(keyCode)), 4));
879 }
880}
881
882int PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(unsigned keycode)
883{
884 switch (keycode) {
885 case GDK_KEY_Cancel:
886 return 0x03; // (03) The Cancel key
887 case GDK_KP_0:
888 return VK_NUMPAD0;// (60) Numeric keypad 0 key
889 case GDK_KP_1:
890 return VK_NUMPAD1;// (61) Numeric keypad 1 key
891 case GDK_KP_2:
892 return VK_NUMPAD2; // (62) Numeric keypad 2 key
893 case GDK_KP_3:
894 return VK_NUMPAD3; // (63) Numeric keypad 3 key
895 case GDK_KP_4:
896 return VK_NUMPAD4; // (64) Numeric keypad 4 key
897 case GDK_KP_5:
898 return VK_NUMPAD5; //(65) Numeric keypad 5 key
899 case GDK_KP_6:
900 return VK_NUMPAD6; // (66) Numeric keypad 6 key
901 case GDK_KP_7:
902 return VK_NUMPAD7; // (67) Numeric keypad 7 key
903 case GDK_KP_8:
904 return VK_NUMPAD8; // (68) Numeric keypad 8 key
905 case GDK_KP_9:
906 return VK_NUMPAD9; // (69) Numeric keypad 9 key
907 case GDK_KP_Multiply:
908 return VK_MULTIPLY; // (6A) Multiply key
909 case GDK_KP_Add:
910 return VK_ADD; // (6B) Add key
911 case GDK_KP_Subtract:
912 return VK_SUBTRACT; // (6D) Subtract key
913 case GDK_KP_Decimal:
914 return VK_DECIMAL; // (6E) Decimal key
915 case GDK_KP_Divide:
916 return VK_DIVIDE; // (6F) Divide key
917
918 case GDK_KP_Page_Up:
919 return VK_PRIOR; // (21) PAGE UP key
920 case GDK_KP_Page_Down:
921 return VK_NEXT; // (22) PAGE DOWN key
922 case GDK_KP_End:
923 return VK_END; // (23) END key
924 case GDK_KP_Home:
925 return VK_HOME; // (24) HOME key
926 case GDK_KP_Left:
927 return VK_LEFT; // (25) LEFT ARROW key
928 case GDK_KP_Up:
929 return VK_UP; // (26) UP ARROW key
930 case GDK_KP_Right:
931 return VK_RIGHT; // (27) RIGHT ARROW key
932 case GDK_KP_Down:
933 return VK_DOWN; // (28) DOWN ARROW key
934
935 case GDK_BackSpace:
936 return VK_BACK; // (08) BACKSPACE key
937 case GDK_ISO_Left_Tab:
938 case GDK_3270_BackTab:
939 case GDK_Tab:
940 return VK_TAB; // (09) TAB key
941 case GDK_Clear:
942 return VK_CLEAR; // (0C) CLEAR key
943 case GDK_ISO_Enter:
944 case GDK_KP_Enter:
945 case GDK_Return:
946 return VK_RETURN; //(0D) Return key
947
948 // VK_SHIFT (10) SHIFT key
949 // VK_CONTROL (11) CTRL key
950
951 case GDK_Menu:
952 return VK_APPS; // (5D) Applications key (Natural keyboard)
953
954 // VK_MENU (12) ALT key
955
956 case GDK_Pause:
957 case GDK_KEY_AudioPause:
958 return VK_PAUSE; // (13) PAUSE key
959 case GDK_Caps_Lock:
960 return VK_CAPITAL; // (14) CAPS LOCK key
961 case GDK_Kana_Lock:
962 case GDK_Kana_Shift:
963 return VK_KANA; // (15) Input Method Editor (IME) Kana mode
964 case GDK_Hangul:
965 return VK_HANGUL; // VK_HANGUL (15) IME Hangul mode
966 // VK_JUNJA (17) IME Junja mode
967 // VK_FINAL (18) IME final mode
968 case GDK_Hangul_Hanja:
969 return VK_HANJA; // (19) IME Hanja mode
970 case GDK_Kanji:
971 return VK_KANJI; // (19) IME Kanji mode
972 case GDK_Escape:
973 return VK_ESCAPE; // (1B) ESC key
974 // VK_CONVERT (1C) IME convert
975 // VK_NONCONVERT (1D) IME nonconvert
976 // VK_ACCEPT (1E) IME accept
977 // VK_MODECHANGE (1F) IME mode change request
978 case GDK_space:
979 return VK_SPACE; // (20) SPACEBAR
980 case GDK_Page_Up:
981 return VK_PRIOR; // (21) PAGE UP key
982 case GDK_Page_Down:
983 return VK_NEXT; // (22) PAGE DOWN key
984 case GDK_End:
985 return VK_END; // (23) END key
986 case GDK_Home:
987 return VK_HOME; // (24) HOME key
988 case GDK_Left:
989 return VK_LEFT; // (25) LEFT ARROW key
990 case GDK_Up:
991 return VK_UP; // (26) UP ARROW key
992 case GDK_Right:
993 return VK_RIGHT; // (27) RIGHT ARROW key
994 case GDK_Down:
995 return VK_DOWN; // (28) DOWN ARROW key
996 case GDK_Select:
997 return VK_SELECT; // (29) SELECT key
998 case GDK_Print:
999 return VK_SNAPSHOT; // (2C) PRINT SCREEN key
1000 case GDK_Execute:
1001 return VK_EXECUTE;// (2B) EXECUTE key
1002 case GDK_Insert:
1003 case GDK_KP_Insert:
1004 return VK_INSERT; // (2D) INS key
1005 case GDK_Delete:
1006 case GDK_KP_Delete:
1007 return VK_DELETE; // (2E) DEL key
1008 case GDK_Help:
1009 return VK_HELP; // (2F) HELP key
1010 case GDK_0:
1011 case GDK_parenright:
1012 return VK_0; // (30) 0) key
1013 case GDK_1:
1014 case GDK_exclam:
1015 return VK_1; // (31) 1 ! key
1016 case GDK_2:
1017 case GDK_at:
1018 return VK_2; // (32) 2 & key
1019 case GDK_3:
1020 case GDK_numbersign:
1021 return VK_3; //case '3': case '#';
1022 case GDK_4:
1023 case GDK_dollar: // (34) 4 key '$';
1024 return VK_4;
1025 case GDK_5:
1026 case GDK_percent:
1027 return VK_5; // (35) 5 key '%'
1028 case GDK_6:
1029 case GDK_asciicircum:
1030 return VK_6; // (36) 6 key '^'
1031 case GDK_7:
1032 case GDK_ampersand:
1033 return VK_7; // (37) 7 key case '&'
1034 case GDK_8:
1035 case GDK_asterisk:
1036 return VK_8; // (38) 8 key '*'
1037 case GDK_9:
1038 case GDK_parenleft:
1039 return VK_9; // (39) 9 key '('
1040 case GDK_a:
1041 case GDK_A:
1042 return VK_A; // (41) A key case 'a': case 'A': return 0x41;
1043 case GDK_b:
1044 case GDK_B:
1045 return VK_B; // (42) B key case 'b': case 'B': return 0x42;
1046 case GDK_c:
1047 case GDK_C:
1048 return VK_C; // (43) C key case 'c': case 'C': return 0x43;
1049 case GDK_d:
1050 case GDK_D:
1051 return VK_D; // (44) D key case 'd': case 'D': return 0x44;
1052 case GDK_e:
1053 case GDK_E:
1054 return VK_E; // (45) E key case 'e': case 'E': return 0x45;
1055 case GDK_f:
1056 case GDK_F:
1057 return VK_F; // (46) F key case 'f': case 'F': return 0x46;
1058 case GDK_g:
1059 case GDK_G:
1060 return VK_G; // (47) G key case 'g': case 'G': return 0x47;
1061 case GDK_h:
1062 case GDK_H:
1063 return VK_H; // (48) H key case 'h': case 'H': return 0x48;
1064 case GDK_i:
1065 case GDK_I:
1066 return VK_I; // (49) I key case 'i': case 'I': return 0x49;
1067 case GDK_j:
1068 case GDK_J:
1069 return VK_J; // (4A) J key case 'j': case 'J': return 0x4A;
1070 case GDK_k:
1071 case GDK_K:
1072 return VK_K; // (4B) K key case 'k': case 'K': return 0x4B;
1073 case GDK_l:
1074 case GDK_L:
1075 return VK_L; // (4C) L key case 'l': case 'L': return 0x4C;
1076 case GDK_m:
1077 case GDK_M:
1078 return VK_M; // (4D) M key case 'm': case 'M': return 0x4D;
1079 case GDK_n:
1080 case GDK_N:
1081 return VK_N; // (4E) N key case 'n': case 'N': return 0x4E;
1082 case GDK_o:
1083 case GDK_O:
1084 return VK_O; // (4F) O key case 'o': case 'O': return 0x4F;
1085 case GDK_p:
1086 case GDK_P:
1087 return VK_P; // (50) P key case 'p': case 'P': return 0x50;
1088 case GDK_q:
1089 case GDK_Q:
1090 return VK_Q; // (51) Q key case 'q': case 'Q': return 0x51;
1091 case GDK_r:
1092 case GDK_R:
1093 return VK_R; // (52) R key case 'r': case 'R': return 0x52;
1094 case GDK_s:
1095 case GDK_S:
1096 return VK_S; // (53) S key case 's': case 'S': return 0x53;
1097 case GDK_t:
1098 case GDK_T:
1099 return VK_T; // (54) T key case 't': case 'T': return 0x54;
1100 case GDK_u:
1101 case GDK_U:
1102 return VK_U; // (55) U key case 'u': case 'U': return 0x55;
1103 case GDK_v:
1104 case GDK_V:
1105 return VK_V; // (56) V key case 'v': case 'V': return 0x56;
1106 case GDK_w:
1107 case GDK_W:
1108 return VK_W; // (57) W key case 'w': case 'W': return 0x57;
1109 case GDK_x:
1110 case GDK_X:
1111 return VK_X; // (58) X key case 'x': case 'X': return 0x58;
1112 case GDK_y:
1113 case GDK_Y:
1114 return VK_Y; // (59) Y key case 'y': case 'Y': return 0x59;
1115 case GDK_z:
1116 case GDK_Z:
1117 return VK_Z; // (5A) Z key case 'z': case 'Z': return 0x5A;
1118 case GDK_Meta_L:
1119 return VK_LWIN; // (5B) Left Windows key (Microsoft Natural keyboard)
1120 case GDK_Meta_R:
1121 return VK_RWIN; // (5C) Right Windows key (Natural keyboard)
1122 case GDK_KEY_Sleep:
1123 return VK_SLEEP; // (5F) Computer Sleep key
1124 // VK_SEPARATOR (6C) Separator key
1125 // VK_SUBTRACT (6D) Subtract key
1126 // VK_DECIMAL (6E) Decimal key
1127 // VK_DIVIDE (6F) Divide key
1128 // handled by key code above
1129
1130 case GDK_Num_Lock:
1131 return VK_NUMLOCK; // (90) NUM LOCK key
1132
1133 case GDK_Scroll_Lock:
1134 return VK_SCROLL; // (91) SCROLL LOCK key
1135
1136 case GDK_Shift_L:
1137 return VK_LSHIFT; // (A0) Left SHIFT key
1138 case GDK_Shift_R:
1139 return VK_RSHIFT; // (A1) Right SHIFT key
1140 case GDK_Control_L:
1141 return VK_LCONTROL; // (A2) Left CONTROL key
1142 case GDK_Control_R:
1143 return VK_RCONTROL; // (A3) Right CONTROL key
1144 case GDK_Alt_L:
1145 return VK_LMENU; // (A4) Left MENU key
1146 case GDK_Alt_R:
1147 return VK_RMENU; // (A5) Right MENU key
1148
1149 case GDK_KEY_Back:
1150 return VK_BROWSER_BACK; // VK_BROWSER_BACK (A6) Windows 2000/XP: Browser Back key
1151 case GDK_KEY_Forward:
1152 return VK_BROWSER_FORWARD; // (A7) Windows 2000/XP: Browser Forward key
1153 case GDK_KEY_Refresh:
1154 return VK_BROWSER_REFRESH; // (A8) Windows 2000/XP: Browser Refresh key
1155 case GDK_KEY_Stop:
1156 return VK_BROWSER_STOP; // (A9) Windows 2000/XP: Browser Stop key
1157 case GDK_KEY_Search:
1158 return VK_BROWSER_SEARCH; // (AA) Windows 2000/XP: Browser Search key
1159 case GDK_KEY_Favorites:
1160 return VK_BROWSER_FAVORITES; // (AB) Windows 2000/XP: Browser Favorites key
1161 case GDK_KEY_HomePage:
1162 return VK_BROWSER_HOME; // (AC) Windows 2000/XP: Browser Start and Home key
1163 case GDK_KEY_AudioMute:
1164 return VK_VOLUME_MUTE; // (AD) Windows 2000/XP: Volume Mute key
1165 case GDK_KEY_AudioLowerVolume:
1166 return VK_VOLUME_DOWN; // (AE) Windows 2000/XP: Volume Down key
1167 case GDK_KEY_AudioRaiseVolume:
1168 return VK_VOLUME_UP; // (AF) Windows 2000/XP: Volume Up key
1169 case GDK_KEY_AudioNext:
1170 return VK_MEDIA_NEXT_TRACK; // (B0) Windows 2000/XP: Next Track key
1171 case GDK_KEY_AudioPrev:
1172 return VK_MEDIA_PREV_TRACK; // (B1) Windows 2000/XP: Previous Track key
1173 case GDK_KEY_AudioStop:
1174 return VK_MEDIA_STOP; // (B2) Windows 2000/XP: Stop Media key
1175 // VK_MEDIA_PLAY_PAUSE (B3) Windows 2000/XP: Play/Pause Media key
1176 // VK_LAUNCH_MAIL (B4) Windows 2000/XP: Start Mail key
1177 case GDK_KEY_AudioMedia:
1178 return VK_MEDIA_LAUNCH_MEDIA_SELECT; // (B5) Windows 2000/XP: Select Media key
1179 // VK_LAUNCH_APP1 (B6) Windows 2000/XP: Start Application 1 key
1180 // VK_LAUNCH_APP2 (B7) Windows 2000/XP: Start Application 2 key
1181
1182 // VK_OEM_1 (BA) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ';:' key
1183 case GDK_semicolon:
1184 case GDK_colon:
1185 return VK_OEM_1; //case ';': case ':': return 0xBA;
1186 // VK_OEM_PLUS (BB) Windows 2000/XP: For any country/region, the '+' key
1187 case GDK_plus:
1188 case GDK_equal:
1189 return VK_OEM_PLUS; //case '=': case '+': return 0xBB;
1190 // VK_OEM_COMMA (BC) Windows 2000/XP: For any country/region, the ',' key
1191 case GDK_comma:
1192 case GDK_less:
1193 return VK_OEM_COMMA; //case ',': case '<': return 0xBC;
1194 // VK_OEM_MINUS (BD) Windows 2000/XP: For any country/region, the '-' key
1195 case GDK_minus:
1196 case GDK_underscore:
1197 return VK_OEM_MINUS; //case '-': case '_': return 0xBD;
1198 // VK_OEM_PERIOD (BE) Windows 2000/XP: For any country/region, the '.' key
1199 case GDK_period:
1200 case GDK_greater:
1201 return VK_OEM_PERIOD; //case '.': case '>': return 0xBE;
1202 // VK_OEM_2 (BF) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '/?' key
1203 case GDK_slash:
1204 case GDK_question:
1205 return VK_OEM_2; //case '/': case '?': return 0xBF;
1206 // VK_OEM_3 (C0) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '`~' key
1207 case GDK_asciitilde:
1208 case GDK_quoteleft:
1209 return VK_OEM_3; //case '`': case '~': return 0xC0;
1210 // VK_OEM_4 (DB) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '[{' key
1211 case GDK_bracketleft:
1212 case GDK_braceleft:
1213 return VK_OEM_4; //case '[': case '{': return 0xDB;
1214 // VK_OEM_5 (DC) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '\|' key
1215 case GDK_backslash:
1216 case GDK_bar:
1217 return VK_OEM_5; //case '\\': case '|': return 0xDC;
1218 // VK_OEM_6 (DD) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ']}' key
1219 case GDK_bracketright:
1220 case GDK_braceright:
1221 return VK_OEM_6; // case ']': case '}': return 0xDD;
1222 // VK_OEM_7 (DE) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
1223 case GDK_quoteright:
1224 case GDK_quotedbl:
1225 return VK_OEM_7; // case '\'': case '"': return 0xDE;
1226 // VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard.
1227 // VK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
1228 case GDK_KEY_AudioRewind:
1229 return 0xE3; // (E3) Android/GoogleTV: Rewind media key (Windows: VK_ICO_HELP Help key on 1984 Olivetti M24 deluxe keyboard)
1230 case GDK_KEY_AudioForward:
1231 return 0xE4; // (E4) Android/GoogleTV: Fast forward media key (Windows: VK_ICO_00 '00' key on 1984 Olivetti M24 deluxe keyboard)
1232 // VK_PROCESSKEY (E5) Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key
1233 // VK_PACKET (E7) Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT,SendInput, WM_KEYDOWN, and WM_KEYUP
1234 // VK_ATTN (F6) Attn key
1235 // VK_CRSEL (F7) CrSel key
1236 // VK_EXSEL (F8) ExSel key
1237 // VK_EREOF (F9) Erase EOF key
1238 case GDK_KEY_AudioPlay:
1239 return VK_PLAY; // VK_PLAY (FA) Play key
1240 // VK_ZOOM (FB) Zoom key
1241 // VK_NONAME (FC) Reserved for future use
1242 // VK_PA1 (FD) PA1 key
1243 // VK_OEM_CLEAR (FE) Clear key
1244 case GDK_F1:
1245 case GDK_F2:
1246 case GDK_F3:
1247 case GDK_F4:
1248 case GDK_F5:
1249 case GDK_F6:
1250 case GDK_F7:
1251 case GDK_F8:
1252 case GDK_F9:
1253 case GDK_F10:
1254 case GDK_F11:
1255 case GDK_F12:
1256 case GDK_F13:
1257 case GDK_F14:
1258 case GDK_F15:
1259 case GDK_F16:
1260 case GDK_F17:
1261 case GDK_F18:
1262 case GDK_F19:
1263 case GDK_F20:
1264 case GDK_F21:
1265 case GDK_F22:
1266 case GDK_F23:
1267 case GDK_F24:
1268 return VK_F1 + (keycode - GDK_F1);
1269 case GDK_KEY_VoidSymbol:
1270 return VK_PROCESSKEY;
1271
1272 // TV keycodes from DASE / OCAP / CE-HTML standards.
1273 case GDK_KEY_Red:
1274 return 0x193; // General purpose color-coded media function key, as index 0 (red)
1275 case GDK_KEY_Green:
1276 return 0x194; // General purpose color-coded media function key, as index 1 (green)
1277 case GDK_KEY_Yellow:
1278 return 0x195; // General purpose color-coded media function key, as index 2 (yellow)
1279 case GDK_KEY_Blue:
1280 return 0x196; // General purpose color-coded media function key, as index 3 (blue)
1281 case GDK_KEY_PowerOff:
1282 return 0x199; // Toggle power state
1283 case GDK_KEY_AudioRecord:
1284 return 0x1A0; // Initiate or resume recording of currently selected media
1285 case GDK_KEY_Display:
1286 return 0x1BC; // Swap video sources
1287 case GDK_KEY_Subtitle:
1288 return 0x1CC; // Toggle display of subtitles, if available
1289 case GDK_KEY_Video:
1290 return 0x26F; // Access on-demand content or programs
1291 default:
1292 return 0;
1293 }
1294
1295}
1296
1297String PlatformKeyboardEvent::singleCharacterString(unsigned val)
1298{
1299 switch (val) {
1300 case GDK_ISO_Enter:
1301 case GDK_KP_Enter:
1302 case GDK_Return:
1303 return String("\r");
1304 case GDK_BackSpace:
1305 return String("\x8");
1306 case GDK_Tab:
1307 return String("\t");
1308 default:
1309 gunichar c = gdk_keyval_to_unicode(val);
1310 glong nwc;
1311 gunichar2* uchar16 = g_ucs4_to_utf16(&c, 1, 0, &nwc, 0);
1312
1313 String retVal;
1314 if (uchar16)
1315 retVal = String((UChar*)uchar16, nwc);
1316 else
1317 retVal = String();
1318
1319 g_free(uchar16);
1320
1321 return retVal;
1322 }
1323}
1324
1325static PlatformEvent::Type eventTypeForGdkKeyEvent(GdkEventKey* event)
1326{
1327 return event->type == GDK_KEY_RELEASE ? PlatformEvent::KeyUp : PlatformEvent::KeyDown;
1328}
1329
1330static OptionSet<PlatformEvent::Modifier> modifiersForGdkKeyEvent(GdkEventKey* event)
1331{
1332 OptionSet<PlatformEvent::Modifier> modifiers;
1333 if (event->state & GDK_SHIFT_MASK || event->keyval == GDK_3270_BackTab)
1334 modifiers.add(PlatformEvent::Modifier::ShiftKey);
1335 if (event->state & GDK_CONTROL_MASK)
1336 modifiers.add(PlatformEvent::Modifier::ControlKey);
1337 if (event->state & GDK_MOD1_MASK)
1338 modifiers.add(PlatformEvent::Modifier::AltKey);
1339 if (event->state & GDK_META_MASK)
1340 modifiers.add(PlatformEvent::Modifier::MetaKey);
1341 if (event->state & GDK_LOCK_MASK)
1342 modifiers.add(PlatformEvent::Modifier::CapsLockKey);
1343 return modifiers;
1344}
1345
1346// Keep this in sync with the other platform event constructors
1347PlatformKeyboardEvent::PlatformKeyboardEvent(GdkEventKey* event, const CompositionResults& compositionResults)
1348 : PlatformEvent(eventTypeForGdkKeyEvent(event), modifiersForGdkKeyEvent(event), wallTimeForEvent(event))
1349 , m_text(compositionResults.simpleString.length() ? compositionResults.simpleString : singleCharacterString(event->keyval))
1350 , m_unmodifiedText(m_text)
1351 , m_key(keyValueForGdkKeyCode(event->keyval))
1352 , m_code(keyCodeForHardwareKeyCode(event->hardware_keycode))
1353 , m_keyIdentifier(keyIdentifierForGdkKeyCode(event->keyval))
1354 , m_windowsVirtualKeyCode(windowsKeyCodeForGdkKeyCode(event->keyval))
1355 , m_handledByInputMethod(false)
1356 , m_autoRepeat(false)
1357 , m_isKeypad(event->keyval >= GDK_KP_Space && event->keyval <= GDK_KP_9)
1358 , m_isSystemKey(false)
1359 , m_gdkEventKey(event)
1360 , m_compositionResults(compositionResults)
1361{
1362 // To match the behavior of IE, we return VK_PROCESSKEY for keys that triggered composition results.
1363 if (compositionResults.compositionUpdated())
1364 m_windowsVirtualKeyCode = VK_PROCESSKEY;
1365}
1366
1367void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCompatibilityMode)
1368{
1369 // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
1370 ASSERT(m_type == KeyDown);
1371 m_type = type;
1372
1373 if (backwardCompatibilityMode)
1374 return;
1375
1376 if (type == PlatformEvent::RawKeyDown) {
1377 m_text = String();
1378 m_unmodifiedText = String();
1379 } else if (type == PlatformEvent::Char && m_compositionResults.compositionUpdated()) {
1380 // Having empty text, prevents this Char (which is a DOM keypress) event
1381 // from going to the DOM. Keys that trigger composition events should not
1382 // fire keypress.
1383 m_text = String();
1384 m_unmodifiedText = String();
1385 } else {
1386 m_keyIdentifier = String();
1387 m_windowsVirtualKeyCode = 0;
1388 }
1389}
1390
1391bool PlatformKeyboardEvent::currentCapsLockState()
1392{
1393 return gdk_keymap_get_caps_lock_state(gdk_keymap_get_default());
1394}
1395
1396void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
1397{
1398 GdkModifierType state;
1399 gtk_get_current_event_state(&state);
1400
1401 shiftKey = state & GDK_SHIFT_MASK;
1402 ctrlKey = state & GDK_CONTROL_MASK;
1403 altKey = state & GDK_MOD1_MASK;
1404 metaKey = state & GDK_META_MASK;
1405}
1406
1407bool PlatformKeyboardEvent::modifiersContainCapsLock(unsigned modifier)
1408{
1409 if (!(modifier & GDK_LOCK_MASK))
1410 return false;
1411
1412 // In X11 GDK_LOCK_MASK could be CapsLock or ShiftLock, depending on the modifier mapping of the X server.
1413 // What GTK+ does in the X11 backend is checking if there is a key bound to GDK_KEY_Caps_Lock, so we do
1414 // the same here. This will also return true in Wayland if there's a caps lock key, so it's not worth it
1415 // checking the actual display here.
1416 static bool lockMaskIsCapsLock = false;
1417 static bool initialized = false;
1418 if (!initialized) {
1419 GUniqueOutPtr<GdkKeymapKey> keys;
1420 int entriesCount;
1421 lockMaskIsCapsLock = gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), GDK_KEY_Caps_Lock, &keys.outPtr(), &entriesCount) && entriesCount;
1422 }
1423 return lockMaskIsCapsLock;
1424}
1425
1426}
1427