1/*
2 * Copyright (C) 2010 Company 100, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "PlatformKeyboardEvent.h"
28
29#include "NotImplemented.h"
30#include "WindowsKeyboardCodes.h"
31
32#include <AEEEvent.h>
33#include <AEEIKeysMapping.h>
34#include <AEEKeysMapping.bid>
35#include <AEEStdDef.h>
36#include <AEEVCodes.h>
37
38#include <wtf/brew/RefPtrBrew.h>
39#include <wtf/brew/ShellBrew.h>
40
41namespace WebCore {
42
43static String keyIdentifierForBrewKeyCode(uint16 keyCode)
44{
45    switch (keyCode) {
46    case AVK_LALT:
47    case AVK_RALT:
48        return "Alt";
49    case AVK_LCTRL:
50    case AVK_RCTRL:
51        return "Control";
52    case AVK_LSHIFT:
53    case AVK_RSHIFT:
54        return "Shift";
55    case AVK_CAPLK:
56        return "CapsLock";
57    case AVK_FUNCTION1:
58        return "F1";
59    case AVK_FUNCTION2:
60        return "F2";
61    case AVK_FUNCTION3:
62        return "F3";
63    case AVK_FUNCTION4:
64        return "F4";
65    case AVK_FUNCTION5:
66        return "F5";
67    case AVK_FUNCTION6:
68        return "F6";
69    case AVK_FUNCTION7:
70        return "F7";
71    case AVK_FUNCTION8:
72        return "F8";
73    case AVK_FUNCTION9:
74        return "F9";
75    case AVK_FUNCTION10:
76        return "F10";
77    case AVK_FUNCTION11:
78        return "F11";
79    case AVK_FUNCTION12:
80        return "F12";
81    case AVK_PRSCRN:
82        return "PrintScreen";
83    case AVK_LEFT:
84        return "Left";
85    case AVK_RIGHT:
86        return "Right";
87    case AVK_UP:
88        return "Up";
89    case AVK_DOWN:
90        return "Down";
91    case AVK_TXINSERT:
92        return "Insert";
93    case AVK_ENTER:
94        return "Enter";
95    case AVK_TXHOME:
96        return "Home";
97    case AVK_TXDELETE:
98        // Standard says that DEL becomes U+007F.
99        return "U+007F";
100    case AVK_TXEND:
101        return "End";
102    case AVK_TXPGUP:
103        return "PageUp";
104    case AVK_TXPGDOWN:
105        return "PageDown";
106    case AVK_FUNCTION:
107        return "U+0009";
108    default:
109        return String::format("U+%04X", toASCIIUpper(keyCode));
110    }
111}
112
113static int windowsKeyCodeForKeyEvent(uint16 code)
114{
115    switch (code) {
116    case AVK_CLR:
117        return VK_BACK; // (08) BACKSPACE key
118    case AVK_ENTER:
119        return VK_RETURN; // (0D) Return key
120    case AVK_SPACE:
121        return VK_SPACE; // (20) SPACEBAR
122    case AVK_TXPGUP:
123        return VK_PRIOR; // (21) PAGE UP key
124    case AVK_TXPGDOWN:
125        return VK_NEXT; // (22) PAGE DOWN key
126    case AVK_TXEND:
127        return VK_END; // (23) END key
128    case AVK_TXHOME:
129        return VK_HOME; // (24) HOME key
130    case AVK_LEFT:
131        return VK_LEFT; // (25) LEFT ARROW key
132    case AVK_UP:
133        return VK_UP; // (26) UP ARROW key
134    case AVK_RIGHT:
135        return VK_RIGHT; // (27) RIGHT ARROW key
136    case AVK_DOWN:
137        return VK_DOWN; // (28) DOWN ARROW key
138    case AVK_TXINSERT:
139        return VK_INSERT; // (2D) INS key
140    case AVK_TXDELETE:
141        return VK_DELETE; // (2E) DEL key
142    case AVK_FUNCTION:
143        return VK_TAB; // (09) TAB key
144    default:
145        return 0;
146    }
147}
148
149static inline String singleCharacterString(UChar c)
150{
151    UChar text;
152
153    // Some key codes are not mapped to Unicode characters. Convert them to Unicode characters here.
154    switch (c) {
155    case AVK_0:
156        text = VK_0;
157        break;
158    case AVK_1:
159        text = VK_1;
160        break;
161    case AVK_2:
162        text = VK_2;
163        break;
164    case AVK_3:
165        text = VK_3;
166        break;
167    case AVK_4:
168        text = VK_4;
169        break;
170    case AVK_5:
171        text = VK_5;
172        break;
173    case AVK_6:
174        text = VK_6;
175        break;
176    case AVK_7:
177        text = VK_7;
178        break;
179    case AVK_8:
180        text = VK_8;
181        break;
182    case AVK_9:
183        text = VK_9;
184        break;
185    case AVK_STAR:
186        text = '*';
187        break;
188    case AVK_POUND:
189        text = '#';
190        break;
191    case AVK_FUNCTION1:
192        text = '=';
193        break;
194    case AVK_FUNCTION2:
195        text = '/';
196        break;
197    case AVK_FUNCTION3:
198        text = '_';
199        break;
200    case AVK_PUNC1:
201        text = ',';
202        break;
203    case AVK_PUNC2:
204        text = '.';
205        break;
206    case AVK_SPACE:
207        text = VK_SPACE;
208        break;
209    default:
210        text = c;
211        break;
212    }
213
214    return String(&text, 1);
215}
216
217PlatformKeyboardEvent::PlatformKeyboardEvent(AEEEvent event, uint16 code, uint32 modifiers, Type type)
218    : m_type(type)
219    , m_isKeypad(false)
220    , m_metaKey(false)
221    , m_windowsVirtualKeyCode((type == RawKeyDown || type == KeyUp) ? windowsKeyCodeForKeyEvent(code) : 0)
222{
223    if ((m_type == Char) && modifiers) {
224        RefPtr<IKeysMapping> keysMapping = createRefPtrInstance<IKeysMapping>(AEECLSID_KeysMapping);
225        int result = IKeysMapping_GetMapping(keysMapping.get(), code, modifiers, reinterpret_cast<AECHAR*>(&code));
226        if (result == AEE_SUCCESS) // Reset the modifier when key code is successfully mapped.
227            modifiers = 0;
228    }
229
230    m_text = (type == Char) ? singleCharacterString(code) : String();
231    m_unmodifiedText = (type == Char) ? singleCharacterString(code) : String();
232    m_keyIdentifier = (type == Char) ? String() : keyIdentifierForBrewKeyCode(code);
233    m_nativeVirtualKeyCode = code;
234    m_autoRepeat = modifiers & KB_AUTOREPEAT;
235    m_shiftKey = modifiers & (KB_LSHIFT | KB_RSHIFT);
236    m_ctrlKey = modifiers & (KB_LCTRL | KB_RCTRL);
237    m_altKey = modifiers & (KB_LALT | KB_RALT);
238}
239
240void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool)
241{
242    // No KeyDown events on BREW to disambiguate.
243    ASSERT_NOT_REACHED();
244}
245
246bool PlatformKeyboardEvent::currentCapsLockState()
247{
248    notImplemented();
249    return false;
250}
251
252void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
253{
254    notImplemented();
255    shiftKey = false;
256    ctrlKey = false;
257    altKey = false;
258    metaKey = false;
259}
260
261} // namespace WebCore
262