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 <androidfw/KeycodeLabels.h>
37
38 namespace WebCore {
39
40 // compare to same function in gdk/KeyEventGdk.cpp
windowsKeyCodeForKeyEvent(unsigned int keyCode)41 static 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
keyIdentifierForAndroidKeyCode(int keyCode)169 static 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+%04X", windowsKeyCodeForKeyEvent(keyCode));
195 return String(upper);
196 }
197 }
198
singleCharacterString(UChar32 c)199 static 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
PlatformKeyboardEvent(int keyCode,UChar32 unichar,int repeatCount,bool down,bool cap,bool alt,bool sym)213 PlatformKeyboardEvent::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
currentCapsLockState()248 bool PlatformKeyboardEvent::currentCapsLockState()
249 {
250 notImplemented();
251 return false;
252 }
253
getCurrentModifierState(bool & shiftKey,bool & ctrlKey,bool & altKey,bool & metaKey)254 void 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
disambiguateKeyDownEvent(Type type,bool backwardCompatibilityMode)263 void 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