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 (at) 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 38 namespace WebCore { 39 40 // compare to same function in gdk/KeyEventGdk.cpp 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 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+%06X", windowsKeyCodeForKeyEvent(keyCode)); 195 return String(upper); 196 } 197 } 198 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 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 248 bool PlatformKeyboardEvent::currentCapsLockState() 249 { 250 notImplemented(); 251 return false; 252 } 253 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 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