[BlackBerry] CHHW - Characters that are using 32 bits encoding get trunked to 16bits
[WebKit-https.git] / Source / WebCore / platform / blackberry / PlatformKeyboardEventBlackBerry.cpp
1 /*
2  * Copyright (C) 2009, 2010, 2011 Research In Motion Limited. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include "config.h"
20 #include "PlatformKeyboardEvent.h"
21
22 #include "NotImplemented.h"
23 #include "WindowsKeyboardCodes.h"
24
25 #include <BlackBerryPlatformKeyboardEvent.h>
26 #include <BlackBerryPlatformLog.h>
27 #include <BlackBerryPlatformScreen.h>
28 #include <wtf/CurrentTime.h>
29 #include <wtf/text/CString.h>
30
31 namespace WebCore {
32
33 static String keyIdentifierForBlackBerryCharacter(unsigned character)
34 {
35     switch (character) {
36     case KEYCODE_RETURN:
37     case KEYCODE_KP_ENTER:
38         return "Enter";
39     case KEYCODE_BACKSPACE:
40         return "U+0008";
41     case KEYCODE_DELETE:
42         return "U+007F";
43     case KEYCODE_ESCAPE:
44         return "Escape";
45     case KEYCODE_PAUSE:
46         return "Pause";
47     case KEYCODE_PRINT:
48         return "PrintScreen";
49     case KEYCODE_TAB:
50     case KEYCODE_BACK_TAB:
51         return "U+0009";
52     case KEYCODE_LEFT:
53     case KEYCODE_KP_LEFT:
54         return "Left";
55     case KEYCODE_RIGHT:
56     case KEYCODE_KP_RIGHT:
57         return "Right";
58     case KEYCODE_UP:
59     case KEYCODE_KP_UP:
60         return "Up";
61     case KEYCODE_DOWN:
62     case KEYCODE_KP_DOWN:
63         return "Down";
64     case KEYCODE_KP_DELETE:
65         return "U+007F";
66     case KEYCODE_MENU:
67     case KEYCODE_LEFT_ALT:
68     case KEYCODE_RIGHT_ALT:
69         return "Alt";
70     case KEYCODE_HOME:
71     case KEYCODE_KP_HOME:
72         return "Home";
73     case KEYCODE_INSERT:
74     case KEYCODE_KP_INSERT:
75         return "Insert";
76     case KEYCODE_PG_UP:
77     case KEYCODE_KP_PG_UP:
78         return "PageUp";
79     case KEYCODE_PG_DOWN:
80     case KEYCODE_KP_PG_DOWN:
81         return "PageDown";
82     case KEYCODE_END:
83     case KEYCODE_KP_END:
84         return "End";
85     case KEYCODE_F1:
86         return "F1";
87     case KEYCODE_F2:
88         return "F2";
89     case KEYCODE_F3:
90         return "F3";
91     case KEYCODE_F4:
92         return "F4";
93     case KEYCODE_F5:
94         return "F5";
95     case KEYCODE_F6:
96         return "F6";
97     case KEYCODE_F7:
98         return "F7";
99     case KEYCODE_F8:
100         return "F8";
101     case KEYCODE_F9:
102         return "F9";
103     case KEYCODE_F10:
104         return "F10";
105     case KEYCODE_F11:
106         return "F11";
107     case KEYCODE_F12:
108         return "F12";
109     default:
110         return String::format("U+%04X", WTF::toASCIIUpper(character));
111     }
112 }
113
114 static int windowsKeyCodeForBlackBerryCharacter(unsigned character)
115 {
116     switch (character) {
117     case KEYCODE_RETURN:
118     case KEYCODE_KP_ENTER:
119         return VK_RETURN; // (0D) Return key
120     case KEYCODE_BACKSPACE:
121         return VK_BACK; // (08) BACKSPACE key
122     case KEYCODE_DELETE:
123         return VK_DELETE; // (2E) DEL key
124     case KEYCODE_ESCAPE:
125         return VK_ESCAPE;
126     case KEYCODE_SPACE:
127         return VK_SPACE;
128     case '0':
129     case ')':
130         return VK_0;
131     case '1':
132     case '!':
133         return VK_1;
134     case '2':
135     case '@':
136         return VK_2;
137     case '3':
138     case '#':
139         return VK_3;
140     case '4':
141     case '$':
142         return VK_4;
143     case '5':
144     case '%':
145         return VK_5;
146     case '6':
147     case '^':
148         return VK_6;
149     case '7':
150     case '&':
151         return VK_7;
152     case '8':
153     case '*':
154         return VK_8;
155     case '9':
156     case '(':
157         return VK_9;
158     case 'a':
159     case 'A':
160         return VK_A;
161     case 'b':
162     case 'B':
163         return VK_B;
164     case 'c':
165     case 'C':
166         return VK_C;
167     case 'd':
168     case 'D':
169         return VK_D;
170     case 'e':
171     case 'E':
172         return VK_E;
173     case 'f':
174     case 'F':
175         return VK_F;
176     case 'g':
177     case 'G':
178         return VK_G;
179     case 'h':
180     case 'H':
181         return VK_H;
182     case 'i':
183     case 'I':
184         return VK_I;
185     case 'j':
186     case 'J':
187         return VK_J;
188     case 'k':
189     case 'K':
190         return VK_K;
191     case 'l':
192     case 'L':
193         return VK_L;
194     case 'm':
195     case 'M':
196         return VK_M;
197     case 'n':
198     case 'N':
199         return VK_N;
200     case 'o':
201     case 'O':
202         return VK_O;
203     case 'p':
204     case 'P':
205         return VK_P;
206     case 'q':
207     case 'Q':
208         return VK_Q;
209     case 'r':
210     case 'R':
211         return VK_R;
212     case 's':
213     case 'S':
214         return VK_S;
215     case 't':
216     case 'T':
217         return VK_T;
218     case 'u':
219     case 'U':
220         return VK_U;
221     case 'v':
222     case 'V':
223         return VK_V;
224     case 'w':
225     case 'W':
226         return VK_W;
227     case 'x':
228     case 'X':
229         return VK_X;
230     case 'y':
231     case 'Y':
232         return VK_Y;
233     case 'z':
234     case 'Z':
235         return VK_Z;
236     case '+':
237     case '=':
238         return VK_OEM_PLUS;
239     case '-':
240     case '_':
241         return VK_OEM_MINUS;
242     case '<':
243     case ',':
244         return VK_OEM_COMMA;
245     case '>':
246     case '.':
247         return VK_OEM_PERIOD;
248     case ':':
249     case ';':
250         return VK_OEM_1;
251     case '/':
252     case '?':
253         return VK_OEM_2;
254     case '~':
255     case '`':
256         return VK_OEM_3;
257     case '{':
258     case '[':
259         return VK_OEM_4;
260     case '|':
261     case '\\':
262         return VK_OEM_5;
263     case '}':
264     case ']':
265         return VK_OEM_6;
266     case '"':
267     case '\'':
268         return VK_OEM_7;
269     case KEYCODE_PAUSE:
270         return VK_PAUSE;
271     case KEYCODE_PRINT:
272         return VK_PRINT;
273     case KEYCODE_SCROLL_LOCK:
274         return VK_SCROLL;
275     case KEYCODE_TAB:
276     case KEYCODE_BACK_TAB:
277         return VK_TAB;
278     case KEYCODE_LEFT:
279     case KEYCODE_KP_LEFT:
280         return VK_LEFT;
281     case KEYCODE_RIGHT:
282     case KEYCODE_KP_RIGHT:
283         return VK_RIGHT;
284     case KEYCODE_UP:
285     case KEYCODE_KP_UP:
286         return VK_UP;
287     case KEYCODE_DOWN:
288     case KEYCODE_KP_DOWN:
289         return VK_DOWN;
290     case KEYCODE_KP_DELETE:
291         return VK_DELETE;
292     case KEYCODE_MENU:
293     case KEYCODE_LEFT_ALT:
294     case KEYCODE_RIGHT_ALT:
295         return VK_MENU;
296     case KEYCODE_HOME:
297     case KEYCODE_KP_HOME:
298         return VK_HOME;
299     case KEYCODE_INSERT:
300     case KEYCODE_KP_INSERT:
301         return VK_INSERT;
302     case KEYCODE_PG_UP:
303     case KEYCODE_KP_PG_UP:
304         return VK_PRIOR;
305     case KEYCODE_PG_DOWN:
306     case KEYCODE_KP_PG_DOWN:
307         return VK_NEXT;
308     case KEYCODE_END:
309     case KEYCODE_KP_END:
310         return VK_END;
311     case KEYCODE_CAPS_LOCK:
312         return VK_CAPITAL;
313     case KEYCODE_LEFT_SHIFT:
314     case KEYCODE_RIGHT_SHIFT:
315         return VK_SHIFT;
316     case KEYCODE_LEFT_CTRL:
317     case KEYCODE_RIGHT_CTRL:
318         return VK_CONTROL;
319     case KEYCODE_NUM_LOCK:
320         return VK_NUMLOCK;
321     case KEYCODE_KP_PLUS:
322         return VK_ADD;
323     case KEYCODE_KP_MINUS:
324         return VK_SUBTRACT;
325     case KEYCODE_KP_MULTIPLY:
326         return VK_MULTIPLY;
327     case KEYCODE_KP_DIVIDE:
328         return VK_DIVIDE;
329     case KEYCODE_KP_FIVE:
330         return VK_NUMPAD5;
331     case KEYCODE_F1:
332         return VK_F1;
333     case KEYCODE_F2:
334         return VK_F2;
335     case KEYCODE_F3:
336         return VK_F3;
337     case KEYCODE_F4:
338         return VK_F4;
339     case KEYCODE_F5:
340         return VK_F5;
341     case KEYCODE_F6:
342         return VK_F6;
343     case KEYCODE_F7:
344         return VK_F7;
345     case KEYCODE_F8:
346         return VK_F8;
347     case KEYCODE_F9:
348         return VK_F9;
349     case KEYCODE_F10:
350         return VK_F10;
351     case KEYCODE_F11:
352         return VK_F11;
353     case KEYCODE_F12:
354         return VK_F12;
355     default:
356         return 0;
357     }
358 }
359
360 unsigned adjustCharacterFromOS(unsigned character)
361 {
362     // Use windows key character as ASCII value when possible to enhance readability.
363     switch (character) {
364     case KEYCODE_BACKSPACE:
365         return VK_BACK;
366     case KEYCODE_KP_DELETE:
367     case KEYCODE_DELETE:
368         return 0x7f;
369     case KEYCODE_ESCAPE:
370         return VK_ESCAPE;
371     case KEYCODE_RETURN:
372     case KEYCODE_KP_ENTER:
373         return VK_RETURN;
374     case KEYCODE_KP_PLUS:
375         return VK_ADD;
376     case KEYCODE_KP_MINUS:
377         return VK_SUBTRACT;
378     case KEYCODE_KP_MULTIPLY:
379         return VK_MULTIPLY;
380     case KEYCODE_KP_DIVIDE:
381         return VK_DIVIDE;
382     case KEYCODE_KP_FIVE:
383     case KEYCODE_HOME:
384     case KEYCODE_KP_HOME:
385     case KEYCODE_END:
386     case KEYCODE_KP_END:
387     case KEYCODE_INSERT:
388     case KEYCODE_KP_INSERT:
389     case KEYCODE_PG_UP:
390     case KEYCODE_KP_PG_UP:
391     case KEYCODE_PG_DOWN:
392     case KEYCODE_KP_PG_DOWN:
393     case KEYCODE_MENU:
394     case KEYCODE_LEFT_ALT:
395     case KEYCODE_RIGHT_ALT:
396     case KEYCODE_CAPS_LOCK:
397     case KEYCODE_LEFT_SHIFT:
398     case KEYCODE_RIGHT_SHIFT:
399     case KEYCODE_LEFT_CTRL:
400     case KEYCODE_RIGHT_CTRL:
401     case KEYCODE_NUM_LOCK:
402     case KEYCODE_PRINT:
403     case KEYCODE_SCROLL_LOCK:
404     case KEYCODE_PAUSE:
405     case KEYCODE_F1:
406     case KEYCODE_F2:
407     case KEYCODE_F3:
408     case KEYCODE_F4:
409     case KEYCODE_F5:
410     case KEYCODE_F6:
411     case KEYCODE_F7:
412     case KEYCODE_F8:
413     case KEYCODE_F9:
414     case KEYCODE_F10:
415     case KEYCODE_F11:
416     case KEYCODE_F12:
417     case KEYCODE_LEFT:
418     case KEYCODE_RIGHT:
419     case KEYCODE_UP:
420     case KEYCODE_DOWN:
421         return 0;
422     default:
423         break;
424     }
425     return character;
426 }
427
428 static inline PlatformKeyboardEvent::Type toWebCorePlatformKeyboardEventType(const BlackBerry::Platform::KeyboardEvent::Type type)
429 {
430     switch (type) {
431     case BlackBerry::Platform::KeyboardEvent::KeyDown:
432         return PlatformEvent::KeyDown;
433     case BlackBerry::Platform::KeyboardEvent::KeyUp:
434         return PlatformEvent::KeyUp;
435     case BlackBerry::Platform::KeyboardEvent::KeyChar:
436     default:
437         return PlatformEvent::Char;
438     }
439 }
440
441 PlatformKeyboardEvent::PlatformKeyboardEvent(const BlackBerry::Platform::KeyboardEvent& event)
442     : PlatformEvent(toWebCorePlatformKeyboardEventType(event.type()), event.shiftActive() || (event.character() == KEYCODE_BACK_TAB), event.ctrlActive(), event.altActive(), false, currentTime())
443     , m_keyIdentifier(keyIdentifierForBlackBerryCharacter(event.character()))
444     , m_windowsVirtualKeyCode(windowsKeyCodeForBlackBerryCharacter(event.character()))
445     , m_autoRepeat(false)
446     , m_isKeypad(false)
447     , m_unmodifiedCharacter(event.character())
448 {
449     unsigned character = adjustCharacterFromOS(event.character());
450     UChar utf16[3] = {0};
451     int destLength = 0;
452     UErrorCode ec = U_ZERO_ERROR;
453     u_strFromUTF32(utf16, 3, &destLength, reinterpret_cast<UChar32*>(&character), 1, &ec);
454     if (ec) {
455         BBLOG(BlackBerry::Platform::LogLevelCritical, "PlatformKeyboardEvent::PlatformKeyboardEvent Error converting 0x%x to string ec (%d).", character, ec);
456         return;
457     }
458     m_text = String(utf16, destLength);
459     m_unmodifiedText = m_text;
460
461     if (event.character() == KEYCODE_BACK_TAB)
462         m_modifiers |= ShiftKey; // BackTab should be treated as Shift + Tab.
463
464     BBLOG(BlackBerry::Platform::LogLevelInfo, "Keyboard event received text=%lc, keyIdentifier=%s, windowsVirtualKeyCode=%d", event.character(), m_keyIdentifier.latin1().data(), m_windowsVirtualKeyCode);
465 }
466
467 bool PlatformKeyboardEvent::currentCapsLockState()
468 {
469     notImplemented();
470     return false;
471 }
472
473 void PlatformKeyboardEvent::disambiguateKeyDownEvent(PlatformEvent::Type type, bool backwardCompatibilityMode)
474 {
475     // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
476     ASSERT(m_type == PlatformEvent::KeyDown);
477     m_type = type;
478
479     if (backwardCompatibilityMode)
480         return;
481
482     if (type == PlatformEvent::RawKeyDown) {
483         m_text = String();
484         m_unmodifiedText = String();
485     } else {
486         m_keyIdentifier = String();
487         m_windowsVirtualKeyCode = 0;
488     }
489 }
490
491 void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
492 {
493     int modifiers = BlackBerry::Platform::Graphics::Screen::primaryScreen()->getCurrentModifiersState();
494     shiftKey = modifiers & KEYMOD_SHIFT;
495     ctrlKey = modifiers & KEYMOD_CTRL;
496     altKey = modifiers & KEYMOD_ALT;
497     metaKey = false;
498 }
499
500 } // namespace WebCore