KeyEventAndroid.cpp revision cad810f21b803229eb11403f9209855525a25d57
1/*
2 * Copyright 2007, The Android Open Source Project
3 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
4 * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
5 * Copyright (C) 2007 Holger Hans Peter Freyther
6 * Copyright (C) 2008 Collabora, Ltd.  All rights reserved.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *  * Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "PlatformKeyboardEvent.h"
33
34#include "NotImplemented.h"
35#include "WindowsKeyboardCodes.h"
36#include <ui/KeycodeLabels.h>
37
38namespace WebCore {
39
40// compare to same function in gdk/KeyEventGdk.cpp
41static int windowsKeyCodeForKeyEvent(unsigned int keyCode)
42{
43    // Does not provide all key codes, and does not handle all keys.
44    switch (keyCode) {
45    case AKEYCODE_DEL:
46        return VK_BACK;
47    case AKEYCODE_TAB:
48        return VK_TAB;
49    case AKEYCODE_CLEAR:
50        return VK_CLEAR;
51    case AKEYCODE_DPAD_CENTER:
52    case AKEYCODE_ENTER:
53        return VK_RETURN;
54    case AKEYCODE_SHIFT_LEFT:
55    case AKEYCODE_SHIFT_RIGHT:
56        return VK_SHIFT;
57    // back will serve as escape, although we probably do not have access to it
58    case AKEYCODE_BACK:
59        return VK_ESCAPE;
60    case AKEYCODE_SPACE:
61        return VK_SPACE;
62    case AKEYCODE_HOME:
63        return VK_HOME;
64    case AKEYCODE_DPAD_LEFT:
65        return VK_LEFT;
66    case AKEYCODE_DPAD_UP:
67        return VK_UP;
68    case AKEYCODE_DPAD_RIGHT:
69        return VK_RIGHT;
70    case AKEYCODE_DPAD_DOWN:
71        return VK_DOWN;
72    case AKEYCODE_0:
73        return VK_0;
74    case AKEYCODE_1:
75        return VK_1;
76    case AKEYCODE_2:
77        return VK_2;
78    case AKEYCODE_3:
79        return VK_3;
80    case AKEYCODE_4:
81        return VK_4;
82    case AKEYCODE_5:
83        return VK_5;
84    case AKEYCODE_6:
85        return VK_6;
86    case AKEYCODE_7:
87        return VK_7;
88    case AKEYCODE_8:
89        return VK_8;
90    case AKEYCODE_9:
91        return VK_9;
92    case AKEYCODE_A:
93        return VK_A;
94    case AKEYCODE_B:
95        return VK_B;
96    case AKEYCODE_C:
97        return VK_C;
98    case AKEYCODE_D:
99        return VK_D;
100    case AKEYCODE_E:
101        return VK_E;
102    case AKEYCODE_F:
103        return VK_F;
104    case AKEYCODE_G:
105        return VK_G;
106    case AKEYCODE_H:
107        return VK_H;
108    case AKEYCODE_I:
109        return VK_I;
110    case AKEYCODE_J:
111        return VK_J;
112    case AKEYCODE_K:
113        return VK_K;
114    case AKEYCODE_L:
115        return VK_L;
116    case AKEYCODE_M:
117        return VK_M;
118    case AKEYCODE_N:
119        return VK_N;
120    case AKEYCODE_O:
121        return VK_O;
122    case AKEYCODE_P:
123        return VK_P;
124    case AKEYCODE_Q:
125        return VK_Q;
126    case AKEYCODE_R:
127        return VK_R;
128    case AKEYCODE_S:
129        return VK_S;
130    case AKEYCODE_T:
131        return VK_T;
132    case AKEYCODE_U:
133        return VK_U;
134    case AKEYCODE_V:
135        return VK_V;
136    case AKEYCODE_W:
137        return VK_W;
138    case AKEYCODE_X:
139        return VK_X;
140    case AKEYCODE_Y:
141        return VK_Y;
142    case AKEYCODE_Z:
143        return VK_Z;
144    // colon
145    case AKEYCODE_SEMICOLON:
146        return VK_OEM_1;
147    case AKEYCODE_COMMA:
148        return VK_OEM_COMMA;
149    case AKEYCODE_MINUS:
150        return VK_OEM_MINUS;
151    case AKEYCODE_EQUALS:
152        return VK_OEM_PLUS;
153    case AKEYCODE_PERIOD:
154        return VK_OEM_PERIOD;
155    case AKEYCODE_SLASH:
156        return VK_OEM_2;
157    // maybe not the right choice
158    case AKEYCODE_LEFT_BRACKET:
159        return VK_OEM_4;
160    case AKEYCODE_BACKSLASH:
161        return VK_OEM_5;
162    case AKEYCODE_RIGHT_BRACKET:
163        return VK_OEM_6;
164    default:
165        return 0;
166    }
167}
168
169static String keyIdentifierForAndroidKeyCode(int keyCode)
170{
171    // Does not return all of the same key identifiers, and
172    // does not handle all the keys.
173    switch (keyCode) {
174    case AKEYCODE_CLEAR:
175        return "Clear";
176    case AKEYCODE_ENTER:
177    case AKEYCODE_DPAD_CENTER:
178        return "Enter";
179    case AKEYCODE_HOME:
180        return "Home";
181    case AKEYCODE_DPAD_DOWN:
182        return "Down";
183    case AKEYCODE_DPAD_LEFT:
184        return "Left";
185    case AKEYCODE_DPAD_RIGHT:
186        return "Right";
187    case AKEYCODE_DPAD_UP:
188        return "Up";
189    // Standard says that DEL becomes U+00007F.
190    case AKEYCODE_DEL:
191        return "U+00007F";
192    default:
193        char upper[16];
194        sprintf(upper, "U+%06X", windowsKeyCodeForKeyEvent(keyCode));
195        return String(upper);
196    }
197}
198
199static inline String singleCharacterString(UChar32 c)
200{
201    if (!c)
202        return String();
203    if (c > 0xffff) {
204        UChar lead = U16_LEAD(c);
205        UChar trail = U16_TRAIL(c);
206        UChar utf16[2] = {lead, trail};
207        return String(utf16, 2);
208    }
209    UChar n = (UChar)c;
210    return String(&n, 1);
211}
212
213PlatformKeyboardEvent::PlatformKeyboardEvent(int keyCode, UChar32 unichar,
214        int repeatCount, bool down, bool cap, bool alt, bool sym)
215    : m_type(down ? KeyDown : KeyUp)
216    , m_text(singleCharacterString(unichar))
217    , m_unmodifiedText(singleCharacterString(unichar))
218    , m_keyIdentifier(keyIdentifierForAndroidKeyCode(keyCode))
219    , m_autoRepeat(repeatCount > 0)
220    , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(keyCode))
221    , m_nativeVirtualKeyCode(keyCode)
222    , m_isKeypad(false)
223    , m_shiftKey(cap ? ShiftKey : 0)
224    , m_ctrlKey(sym ? CtrlKey : 0)
225    , m_altKey(alt ? AltKey : 0)
226    , m_metaKey(0)
227    // added for android
228    , m_repeatCount(repeatCount)
229    , m_unichar(unichar)
230{
231    // Copied from the mac port
232    if (m_windowsVirtualKeyCode == '\r') {
233        m_text = "\r";
234        m_unmodifiedText = "\r";
235    }
236
237    if (m_text == "\x7F")
238        m_text = "\x8";
239    if (m_unmodifiedText == "\x7F")
240        m_unmodifiedText = "\x8";
241
242    if (m_windowsVirtualKeyCode == 9) {
243        m_text = "\x9";
244        m_unmodifiedText = "\x9";
245    }
246}
247
248bool PlatformKeyboardEvent::currentCapsLockState()
249{
250    notImplemented();
251    return false;
252}
253
254void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
255{
256    notImplemented();
257    shiftKey = false;
258    ctrlKey = false;
259    altKey = false;
260    metaKey = false;
261}
262
263void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCompatibilityMode)
264{
265    // Copied with modification from the mac port.
266    ASSERT(m_type == KeyDown);
267    ASSERT(type == RawKeyDown || type == Char);
268    m_type = type;
269    if (backwardCompatibilityMode)
270        return;
271
272    if (type == RawKeyDown) {
273        m_text = String();
274        m_unmodifiedText = String();
275    } else {
276        m_keyIdentifier = String();
277        m_windowsVirtualKeyCode = 0;
278    }
279}
280
281} // namespace WebCore
282