OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2009 Google 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY 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 "sky/engine/config.h" | |
32 #include "sky/engine/web/WebInputEventConversion.h" | |
33 | |
34 #include "sky/engine/core/events/KeyboardEvent.h" | |
35 #include "sky/engine/core/frame/FrameHost.h" | |
36 #include "sky/engine/core/frame/FrameView.h" | |
37 #include "sky/engine/core/page/Page.h" | |
38 #include "sky/engine/core/rendering/RenderObject.h" | |
39 #include "sky/engine/platform/KeyboardCodes.h" | |
40 #include "sky/engine/platform/Widget.h" | |
41 | |
42 namespace blink { | |
43 | |
44 static const double millisPerSecond = 1000.0; | |
45 | |
46 // MakePlatformKeyboardEvent -------------------------------------------------- | |
47 | |
48 inline PlatformEvent::Type toPlatformKeyboardEventType(WebInputEvent::Type type) | |
49 { | |
50 switch (type) { | |
51 case WebInputEvent::KeyUp: | |
52 return PlatformEvent::KeyUp; | |
53 case WebInputEvent::KeyDown: | |
54 return PlatformEvent::KeyDown; | |
55 case WebInputEvent::RawKeyDown: | |
56 return PlatformEvent::RawKeyDown; | |
57 case WebInputEvent::Char: | |
58 return PlatformEvent::Char; | |
59 default: | |
60 ASSERT_NOT_REACHED(); | |
61 } | |
62 return PlatformEvent::KeyDown; | |
63 } | |
64 | |
65 PlatformKeyboardEventBuilder::PlatformKeyboardEventBuilder(const WebKeyboardEven
t& e) | |
66 { | |
67 m_type = toPlatformKeyboardEventType(e.type); | |
68 m_text = String(e.text); | |
69 m_unmodifiedText = String(e.unmodifiedText); | |
70 m_keyIdentifier = String(e.keyIdentifier); | |
71 m_autoRepeat = (e.modifiers & WebInputEvent::IsAutoRepeat); | |
72 m_nativeVirtualKeyCode = e.nativeKeyCode; | |
73 m_isKeypad = (e.modifiers & WebInputEvent::IsKeyPad); | |
74 m_isSystemKey = e.isSystemKey; | |
75 | |
76 m_modifiers = 0; | |
77 if (e.modifiers & WebInputEvent::ShiftKey) | |
78 m_modifiers |= PlatformEvent::ShiftKey; | |
79 if (e.modifiers & WebInputEvent::ControlKey) | |
80 m_modifiers |= PlatformEvent::CtrlKey; | |
81 if (e.modifiers & WebInputEvent::AltKey) | |
82 m_modifiers |= PlatformEvent::AltKey; | |
83 if (e.modifiers & WebInputEvent::MetaKey) | |
84 m_modifiers |= PlatformEvent::MetaKey; | |
85 | |
86 // FIXME: PlatformKeyboardEvents expect a locational version of the keycode
(e.g. VK_LSHIFT | |
87 // instead of VK_SHIFT). This should be changed so the location/keycode are
stored separately, | |
88 // as in other places in the code. | |
89 m_windowsVirtualKeyCode = e.windowsKeyCode; | |
90 if (e.windowsKeyCode == VK_SHIFT) { | |
91 if (e.modifiers & WebInputEvent::IsLeft) | |
92 m_windowsVirtualKeyCode = VK_LSHIFT; | |
93 else if (e.modifiers & WebInputEvent::IsRight) | |
94 m_windowsVirtualKeyCode = VK_RSHIFT; | |
95 } else if (e.windowsKeyCode == VK_CONTROL) { | |
96 if (e.modifiers & WebInputEvent::IsLeft) | |
97 m_windowsVirtualKeyCode = VK_LCONTROL; | |
98 else if (e.modifiers & WebInputEvent::IsRight) | |
99 m_windowsVirtualKeyCode = VK_RCONTROL; | |
100 } else if (e.windowsKeyCode == VK_MENU) { | |
101 if (e.modifiers & WebInputEvent::IsLeft) | |
102 m_windowsVirtualKeyCode = VK_LMENU; | |
103 else if (e.modifiers & WebInputEvent::IsRight) | |
104 m_windowsVirtualKeyCode = VK_RMENU; | |
105 } | |
106 | |
107 } | |
108 | |
109 void PlatformKeyboardEventBuilder::setKeyType(Type type) | |
110 { | |
111 // According to the behavior of Webkit in Windows platform, | |
112 // we need to convert KeyDown to RawKeydown and Char events | |
113 // See WebKit/WebKit/Win/WebView.cpp | |
114 ASSERT(m_type == KeyDown); | |
115 ASSERT(type == RawKeyDown || type == Char); | |
116 m_type = type; | |
117 | |
118 if (type == RawKeyDown) { | |
119 m_text = String(); | |
120 m_unmodifiedText = String(); | |
121 } else { | |
122 m_keyIdentifier = String(); | |
123 m_windowsVirtualKeyCode = 0; | |
124 } | |
125 } | |
126 | |
127 // Please refer to bug http://b/issue?id=961192, which talks about Webkit | |
128 // keyboard event handling changes. It also mentions the list of keys | |
129 // which don't have associated character events. | |
130 bool PlatformKeyboardEventBuilder::isCharacterKey() const | |
131 { | |
132 switch (windowsVirtualKeyCode()) { | |
133 case VKEY_BACK: | |
134 case VKEY_ESCAPE: | |
135 return false; | |
136 } | |
137 return true; | |
138 } | |
139 | |
140 static int getWebInputModifiers(const UIEventWithKeyState& event) | |
141 { | |
142 int modifiers = 0; | |
143 if (event.ctrlKey()) | |
144 modifiers |= WebInputEvent::ControlKey; | |
145 if (event.shiftKey()) | |
146 modifiers |= WebInputEvent::ShiftKey; | |
147 if (event.altKey()) | |
148 modifiers |= WebInputEvent::AltKey; | |
149 if (event.metaKey()) | |
150 modifiers |= WebInputEvent::MetaKey; | |
151 return modifiers; | |
152 } | |
153 | |
154 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event) | |
155 { | |
156 if (event.type() == EventTypeNames::keydown) | |
157 type = KeyDown; | |
158 else if (event.type() == EventTypeNames::keyup) | |
159 type = WebInputEvent::KeyUp; | |
160 else if (event.type() == EventTypeNames::keypress) | |
161 type = WebInputEvent::Char; | |
162 else | |
163 return; // Skip all other keyboard events. | |
164 | |
165 modifiers = getWebInputModifiers(event); | |
166 if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_NUMPAD) | |
167 modifiers |= WebInputEvent::IsKeyPad; | |
168 else if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_LEFT) | |
169 modifiers |= WebInputEvent::IsLeft; | |
170 else if (event.location() == KeyboardEvent::DOM_KEY_LOCATION_RIGHT) | |
171 modifiers |= WebInputEvent::IsRight; | |
172 | |
173 timeStampSeconds = event.timeStamp() / millisPerSecond; | |
174 windowsKeyCode = event.keyCode(); | |
175 | |
176 // The platform keyevent does not exist if the event was created using | |
177 // initKeyboardEvent. | |
178 if (!event.keyEvent()) | |
179 return; | |
180 nativeKeyCode = event.keyEvent()->nativeVirtualKeyCode(); | |
181 unsigned numberOfCharacters = std::min(event.keyEvent()->text().length(), st
atic_cast<unsigned>(textLengthCap)); | |
182 for (unsigned i = 0; i < numberOfCharacters; ++i) { | |
183 text[i] = event.keyEvent()->text()[i]; | |
184 unmodifiedText[i] = event.keyEvent()->unmodifiedText()[i]; | |
185 } | |
186 memcpy(keyIdentifier, event.keyIdentifier().ascii().data(), event.keyIdentif
ier().length()); | |
187 } | |
188 | |
189 WebInputEvent::Type toWebKeyboardEventType(PlatformEvent::Type type) | |
190 { | |
191 switch (type) { | |
192 case PlatformEvent::KeyUp: | |
193 return WebInputEvent::KeyUp; | |
194 case PlatformEvent::KeyDown: | |
195 return WebInputEvent::KeyDown; | |
196 case PlatformEvent::RawKeyDown: | |
197 return WebInputEvent::RawKeyDown; | |
198 case PlatformEvent::Char: | |
199 return WebInputEvent::Char; | |
200 default: | |
201 return WebInputEvent::Undefined; | |
202 } | |
203 } | |
204 | |
205 int toWebKeyboardEventModifiers(int modifiers) | |
206 { | |
207 int newModifiers = 0; | |
208 if (modifiers & PlatformEvent::ShiftKey) | |
209 newModifiers |= WebInputEvent::ShiftKey; | |
210 if (modifiers & PlatformEvent::CtrlKey) | |
211 newModifiers |= WebInputEvent::ControlKey; | |
212 if (modifiers & PlatformEvent::AltKey) | |
213 newModifiers |= WebInputEvent::AltKey; | |
214 if (modifiers & PlatformEvent::MetaKey) | |
215 newModifiers |= WebInputEvent::MetaKey; | |
216 return newModifiers; | |
217 } | |
218 | |
219 WebKeyboardEventBuilder::WebKeyboardEventBuilder(const PlatformKeyboardEvent& ev
ent) | |
220 { | |
221 type = toWebKeyboardEventType(event.type()); | |
222 modifiers = toWebKeyboardEventModifiers(event.modifiers()); | |
223 if (event.isAutoRepeat()) | |
224 modifiers |= WebInputEvent::IsAutoRepeat; | |
225 if (event.isKeypad()) | |
226 modifiers |= WebInputEvent::IsKeyPad; | |
227 isSystemKey = event.isSystemKey(); | |
228 nativeKeyCode = event.nativeVirtualKeyCode(); | |
229 | |
230 windowsKeyCode = windowsKeyCodeWithoutLocation(event.windowsVirtualKeyCode()
); | |
231 modifiers |= locationModifiersFromWindowsKeyCode(event.windowsVirtualKeyCode
()); | |
232 | |
233 event.text().copyTo(text, 0, textLengthCap); | |
234 event.unmodifiedText().copyTo(unmodifiedText, 0, textLengthCap); | |
235 memcpy(keyIdentifier, event.keyIdentifier().ascii().data(), std::min(static_
cast<unsigned>(keyIdentifierLengthCap), event.keyIdentifier().length())); | |
236 } | |
237 | |
238 } // namespace blink | |
OLD | NEW |