IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / browser / renderer_host / web_input_event_aura.cc
blobf35d37740e5e52eac5e6f229b1b07c3ca2ee2217
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/web_input_event_aura.h"
7 #include "content/browser/renderer_host/ui_events_helper.h"
8 #include "ui/aura/window.h"
9 #include "ui/events/event.h"
10 #include "ui/events/event_utils.h"
12 #if defined(USE_OZONE)
13 #include "ui/events/keycodes/keyboard_code_conversion.h"
14 #endif
16 namespace content {
18 #if defined(USE_X11) || defined(USE_OZONE)
19 // From third_party/WebKit/Source/web/gtk/WebInputEventFactory.cpp:
20 blink::WebUChar GetControlCharacter(int windows_key_code, bool shift) {
21 if (windows_key_code >= ui::VKEY_A &&
22 windows_key_code <= ui::VKEY_Z) {
23 // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A
24 return windows_key_code - ui::VKEY_A + 1;
26 if (shift) {
27 // following graphics chars require shift key to input.
28 switch (windows_key_code) {
29 // ctrl-@ maps to \x00 (Null byte)
30 case ui::VKEY_2:
31 return 0;
32 // ctrl-^ maps to \x1E (Record separator, Information separator two)
33 case ui::VKEY_6:
34 return 0x1E;
35 // ctrl-_ maps to \x1F (Unit separator, Information separator one)
36 case ui::VKEY_OEM_MINUS:
37 return 0x1F;
38 // Returns 0 for all other keys to avoid inputting unexpected chars.
39 default:
40 break;
42 } else {
43 switch (windows_key_code) {
44 // ctrl-[ maps to \x1B (Escape)
45 case ui::VKEY_OEM_4:
46 return 0x1B;
47 // ctrl-\ maps to \x1C (File separator, Information separator four)
48 case ui::VKEY_OEM_5:
49 return 0x1C;
50 // ctrl-] maps to \x1D (Group separator, Information separator three)
51 case ui::VKEY_OEM_6:
52 return 0x1D;
53 // ctrl-Enter maps to \x0A (Line feed)
54 case ui::VKEY_RETURN:
55 return 0x0A;
56 // Returns 0 for all other keys to avoid inputting unexpected chars.
57 default:
58 break;
61 return 0;
63 #endif
64 #if defined(OS_WIN)
65 blink::WebMouseEvent MakeUntranslatedWebMouseEventFromNativeEvent(
66 base::NativeEvent native_event);
67 blink::WebMouseWheelEvent MakeUntranslatedWebMouseWheelEventFromNativeEvent(
68 base::NativeEvent native_event);
69 blink::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent(
70 base::NativeEvent native_event);
71 blink::WebGestureEvent MakeWebGestureEventFromNativeEvent(
72 base::NativeEvent native_event);
73 #elif defined(USE_X11)
74 blink::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
75 ui::KeyEvent* event);
76 #elif defined(USE_OZONE)
77 blink::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
78 ui::KeyEvent* event) {
79 base::NativeEvent native_event = event->native_event();
80 ui::EventType type = ui::EventTypeFromNative(native_event);
81 blink::WebKeyboardEvent webkit_event;
83 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
84 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
86 switch (type) {
87 case ui::ET_KEY_PRESSED:
88 webkit_event.type = event->is_char() ? blink::WebInputEvent::Char :
89 blink::WebInputEvent::RawKeyDown;
90 break;
91 case ui::ET_KEY_RELEASED:
92 webkit_event.type = blink::WebInputEvent::KeyUp;
93 break;
94 default:
95 NOTREACHED();
98 if (webkit_event.modifiers & blink::WebInputEvent::AltKey)
99 webkit_event.isSystemKey = true;
101 wchar_t character = ui::KeyboardCodeFromNative(native_event);
102 webkit_event.windowsKeyCode = character;
103 webkit_event.nativeKeyCode = character;
105 if (webkit_event.windowsKeyCode == ui::VKEY_RETURN)
106 webkit_event.unmodifiedText[0] = '\r';
107 else
108 webkit_event.unmodifiedText[0] = ui::GetCharacterFromKeyCode(
109 ui::KeyboardCodeFromNative(native_event),
110 ui::EventFlagsFromNative(native_event));
112 if (webkit_event.modifiers & blink::WebInputEvent::ControlKey) {
113 webkit_event.text[0] =
114 GetControlCharacter(
115 webkit_event.windowsKeyCode,
116 webkit_event.modifiers & blink::WebInputEvent::ShiftKey);
117 } else {
118 webkit_event.text[0] = webkit_event.unmodifiedText[0];
121 webkit_event.setKeyIdentifierFromWindowsKeyCode();
123 return webkit_event;
125 #endif
126 #if defined(USE_X11) || defined(USE_OZONE)
127 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
128 ui::ScrollEvent* event) {
129 blink::WebMouseWheelEvent webkit_event;
131 webkit_event.type = blink::WebInputEvent::MouseWheel;
132 webkit_event.button = blink::WebMouseEvent::ButtonNone;
133 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
134 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
135 webkit_event.hasPreciseScrollingDeltas = true;
136 webkit_event.deltaX = event->x_offset();
137 if (event->x_offset_ordinal() != 0.f && event->x_offset() != 0.f) {
138 webkit_event.accelerationRatioX =
139 event->x_offset_ordinal() / event->x_offset();
141 webkit_event.wheelTicksX = webkit_event.deltaX / kPixelsPerTick;
142 webkit_event.deltaY = event->y_offset();
143 webkit_event.wheelTicksY = webkit_event.deltaY / kPixelsPerTick;
144 if (event->y_offset_ordinal() != 0.f && event->y_offset() != 0.f) {
145 webkit_event.accelerationRatioY =
146 event->y_offset_ordinal() / event->y_offset();
148 return webkit_event;
151 blink::WebGestureEvent MakeWebGestureEventFromAuraEvent(
152 ui::ScrollEvent* event) {
153 blink::WebGestureEvent webkit_event;
155 switch (event->type()) {
156 case ui::ET_SCROLL_FLING_START:
157 webkit_event.type = blink::WebInputEvent::GestureFlingStart;
158 webkit_event.data.flingStart.velocityX = event->x_offset();
159 webkit_event.data.flingStart.velocityY = event->y_offset();
160 break;
161 case ui::ET_SCROLL_FLING_CANCEL:
162 webkit_event.type = blink::WebInputEvent::GestureFlingCancel;
163 break;
164 case ui::ET_SCROLL:
165 NOTREACHED() << "Invalid gesture type: " << event->type();
166 break;
167 default:
168 NOTREACHED() << "Unknown gesture type: " << event->type();
171 webkit_event.sourceDevice = blink::WebGestureEvent::Touchpad;
172 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
173 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
174 return webkit_event;
177 #endif
179 blink::WebMouseEvent MakeWebMouseEventFromAuraEvent(
180 ui::MouseEvent* event);
181 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
182 ui::MouseWheelEvent* event);
184 // General approach:
186 // ui::Event only carries a subset of possible event data provided to Aura by
187 // the host platform. WebKit utilizes a larger subset of that information than
188 // Aura itself. WebKit includes some built in cracking functionality that we
189 // rely on to obtain this information cleanly and consistently.
191 // The only place where an ui::Event's data differs from what the underlying
192 // base::NativeEvent would provide is position data, since we would like to
193 // provide coordinates relative to the aura::Window that is hosting the
194 // renderer, not the top level platform window.
196 // The approach is to fully construct a blink::WebInputEvent from the
197 // ui::Event's base::NativeEvent, and then replace the coordinate fields with
198 // the translated values from the ui::Event.
200 // The exception is mouse events on linux. The ui::MouseEvent contains enough
201 // necessary information to construct a WebMouseEvent. So instead of extracting
202 // the information from the XEvent, which can be tricky when supporting both
203 // XInput2 and XInput, the WebMouseEvent is constructed from the
204 // ui::MouseEvent. This will not be necessary once only XInput2 is supported.
207 blink::WebMouseEvent MakeWebMouseEvent(ui::MouseEvent* event) {
208 // Construct an untranslated event from the platform event data.
209 blink::WebMouseEvent webkit_event =
210 #if defined(OS_WIN)
211 // On Windows we have WM_ events comming from desktop and pure aura
212 // events comming from metro mode.
213 event->native_event().message ?
214 MakeUntranslatedWebMouseEventFromNativeEvent(event->native_event()) :
215 MakeWebMouseEventFromAuraEvent(event);
216 #else
217 MakeWebMouseEventFromAuraEvent(event);
218 #endif
219 // Replace the event's coordinate fields with translated position data from
220 // |event|.
221 webkit_event.windowX = webkit_event.x = event->x();
222 webkit_event.windowY = webkit_event.y = event->y();
224 #if defined(OS_WIN)
225 if (event->native_event().message)
226 return webkit_event;
227 #endif
228 const gfx::Point root_point = event->root_location();
229 webkit_event.globalX = root_point.x();
230 webkit_event.globalY = root_point.y();
232 return webkit_event;
235 blink::WebMouseWheelEvent MakeWebMouseWheelEvent(ui::MouseWheelEvent* event) {
236 #if defined(OS_WIN)
237 // Construct an untranslated event from the platform event data.
238 blink::WebMouseWheelEvent webkit_event = event->native_event().message ?
239 MakeUntranslatedWebMouseWheelEventFromNativeEvent(event->native_event()) :
240 MakeWebMouseWheelEventFromAuraEvent(event);
241 #else
242 blink::WebMouseWheelEvent webkit_event =
243 MakeWebMouseWheelEventFromAuraEvent(event);
244 #endif
246 // Replace the event's coordinate fields with translated position data from
247 // |event|.
248 webkit_event.windowX = webkit_event.x = event->x();
249 webkit_event.windowY = webkit_event.y = event->y();
251 const gfx::Point root_point = event->root_location();
252 webkit_event.globalX = root_point.x();
253 webkit_event.globalY = root_point.y();
255 return webkit_event;
258 blink::WebMouseWheelEvent MakeWebMouseWheelEvent(ui::ScrollEvent* event) {
259 #if defined(OS_WIN)
260 // Construct an untranslated event from the platform event data.
261 blink::WebMouseWheelEvent webkit_event =
262 MakeUntranslatedWebMouseWheelEventFromNativeEvent(event->native_event());
263 #else
264 blink::WebMouseWheelEvent webkit_event =
265 MakeWebMouseWheelEventFromAuraEvent(event);
266 #endif
268 // Replace the event's coordinate fields with translated position data from
269 // |event|.
270 webkit_event.windowX = webkit_event.x = event->x();
271 webkit_event.windowY = webkit_event.y = event->y();
273 const gfx::Point root_point = event->root_location();
274 webkit_event.globalX = root_point.x();
275 webkit_event.globalY = root_point.y();
277 return webkit_event;
280 blink::WebKeyboardEvent MakeWebKeyboardEvent(ui::KeyEvent* event) {
281 // Windows can figure out whether or not to construct a RawKeyDown or a Char
282 // WebInputEvent based on the type of message carried in
283 // event->native_event(). X11 is not so fortunate, there is no separate
284 // translated event type, so DesktopHostLinux sends an extra KeyEvent with
285 // is_char() == true. We need to pass the ui::KeyEvent to the X11 function
286 // to detect this case so the right event type can be constructed.
287 #if defined(OS_WIN)
288 // Key events require no translation by the aura system.
289 return MakeWebKeyboardEventFromNativeEvent(event->native_event());
290 #else
291 return MakeWebKeyboardEventFromAuraEvent(event);
292 #endif
295 blink::WebGestureEvent MakeWebGestureEvent(ui::GestureEvent* event) {
296 blink::WebGestureEvent gesture_event;
297 #if defined(OS_WIN)
298 if (event->HasNativeEvent())
299 gesture_event = MakeWebGestureEventFromNativeEvent(event->native_event());
300 else
301 gesture_event = MakeWebGestureEventFromUIEvent(*event);
302 #else
303 gesture_event = MakeWebGestureEventFromUIEvent(*event);
304 #endif
306 gesture_event.x = event->x();
307 gesture_event.y = event->y();
309 const gfx::Point root_point = event->root_location();
310 gesture_event.globalX = root_point.x();
311 gesture_event.globalY = root_point.y();
313 return gesture_event;
316 blink::WebGestureEvent MakeWebGestureEvent(ui::ScrollEvent* event) {
317 blink::WebGestureEvent gesture_event;
319 #if defined(OS_WIN)
320 gesture_event = MakeWebGestureEventFromNativeEvent(event->native_event());
321 #else
322 gesture_event = MakeWebGestureEventFromAuraEvent(event);
323 #endif
325 gesture_event.x = event->x();
326 gesture_event.y = event->y();
328 const gfx::Point root_point = event->root_location();
329 gesture_event.globalX = root_point.x();
330 gesture_event.globalY = root_point.y();
332 return gesture_event;
335 blink::WebGestureEvent MakeWebGestureEventFlingCancel() {
336 blink::WebGestureEvent gesture_event;
338 // All other fields are ignored on a GestureFlingCancel event.
339 gesture_event.type = blink::WebInputEvent::GestureFlingCancel;
340 gesture_event.sourceDevice = blink::WebGestureEvent::Touchpad;
341 return gesture_event;
344 blink::WebMouseEvent MakeWebMouseEventFromAuraEvent(ui::MouseEvent* event) {
345 blink::WebMouseEvent webkit_event;
347 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
348 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
350 webkit_event.button = blink::WebMouseEvent::ButtonNone;
351 if (event->flags() & ui::EF_LEFT_MOUSE_BUTTON)
352 webkit_event.button = blink::WebMouseEvent::ButtonLeft;
353 if (event->flags() & ui::EF_MIDDLE_MOUSE_BUTTON)
354 webkit_event.button = blink::WebMouseEvent::ButtonMiddle;
355 if (event->flags() & ui::EF_RIGHT_MOUSE_BUTTON)
356 webkit_event.button = blink::WebMouseEvent::ButtonRight;
358 switch (event->type()) {
359 case ui::ET_MOUSE_PRESSED:
360 webkit_event.type = blink::WebInputEvent::MouseDown;
361 webkit_event.clickCount = event->GetClickCount();
362 break;
363 case ui::ET_MOUSE_RELEASED:
364 webkit_event.type = blink::WebInputEvent::MouseUp;
365 webkit_event.clickCount = event->GetClickCount();
366 break;
367 case ui::ET_MOUSE_ENTERED:
368 case ui::ET_MOUSE_EXITED:
369 case ui::ET_MOUSE_MOVED:
370 case ui::ET_MOUSE_DRAGGED:
371 webkit_event.type = blink::WebInputEvent::MouseMove;
372 break;
373 default:
374 NOTIMPLEMENTED() << "Received unexpected event: " << event->type();
375 break;
378 return webkit_event;
381 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
382 ui::MouseWheelEvent* event) {
383 blink::WebMouseWheelEvent webkit_event;
385 webkit_event.type = blink::WebInputEvent::MouseWheel;
386 webkit_event.button = blink::WebMouseEvent::ButtonNone;
387 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
388 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
389 webkit_event.deltaX = event->x_offset();
390 webkit_event.deltaY = event->y_offset();
391 webkit_event.wheelTicksX = webkit_event.deltaX / kPixelsPerTick;
392 webkit_event.wheelTicksY = webkit_event.deltaY / kPixelsPerTick;
394 return webkit_event;
397 } // namespace content