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 // Portions based heavily on:
6 // third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.cpp
9 * Copyright (C) 2006-2011 Google Inc. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are
15 * * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above
18 * copyright notice, this list of conditions and the following disclaimer
19 * in the documentation and/or other materials provided with the
21 * * Neither the name of Google Inc. nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include "content/browser/renderer_host/web_input_event_aura.h"
40 #include <X11/keysym.h>
42 #include <X11/Xutil.h>
45 #include "base/event_types.h"
46 #include "base/logging.h"
47 #include "content/browser/renderer_host/ui_events_helper.h"
48 #include "ui/base/events/event.h"
49 #include "ui/base/events/event_constants.h"
50 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
51 #include "ui/base/keycodes/keyboard_codes.h"
55 // chromium WebKit does not provide a WebInputEventFactory for X11, so we have
56 // to do the work here ourselves.
60 int XKeyEventToWindowsKeyCode(XKeyEvent
* event
) {
61 int windows_key_code
=
62 ui::KeyboardCodeFromXKeyEvent(reinterpret_cast<XEvent
*>(event
));
63 if (windows_key_code
== ui::VKEY_SHIFT
||
64 windows_key_code
== ui::VKEY_CONTROL
||
65 windows_key_code
== ui::VKEY_MENU
) {
66 // To support DOM3 'location' attribute, we need to lookup an X KeySym and
67 // set ui::VKEY_[LR]XXX instead of ui::VKEY_XXX.
68 KeySym keysym
= XK_VoidSymbol
;
69 XLookupString(event
, NULL
, 0, &keysym
, NULL
);
72 return ui::VKEY_LSHIFT
;
74 return ui::VKEY_RSHIFT
;
76 return ui::VKEY_LCONTROL
;
78 return ui::VKEY_RCONTROL
;
81 return ui::VKEY_LMENU
;
84 return ui::VKEY_RMENU
;
87 return windows_key_code
;
91 // third_party/WebKit/Source/WebKit/chromium/src/gtk/WebInputEventFactory.cpp:
92 WebKit::WebUChar
GetControlCharacter(int windows_key_code
, bool shift
) {
93 if (windows_key_code
>= ui::VKEY_A
&&
94 windows_key_code
<= ui::VKEY_Z
) {
95 // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A
96 return windows_key_code
- ui::VKEY_A
+ 1;
99 // following graphics chars require shift key to input.
100 switch (windows_key_code
) {
101 // ctrl-@ maps to \x00 (Null byte)
104 // ctrl-^ maps to \x1E (Record separator, Information separator two)
107 // ctrl-_ maps to \x1F (Unit separator, Information separator one)
108 case ui::VKEY_OEM_MINUS
:
110 // Returns 0 for all other keys to avoid inputting unexpected chars.
115 switch (windows_key_code
) {
116 // ctrl-[ maps to \x1B (Escape)
119 // ctrl-\ maps to \x1C (File separator, Information separator four)
122 // ctrl-] maps to \x1D (Group separator, Information separator three)
125 // ctrl-Enter maps to \x0A (Line feed)
126 case ui::VKEY_RETURN
:
128 // Returns 0 for all other keys to avoid inputting unexpected chars.
138 WebKit::WebMouseWheelEvent
MakeWebMouseWheelEventFromAuraEvent(
139 ui::ScrollEvent
* event
) {
140 WebKit::WebMouseWheelEvent webkit_event
;
142 webkit_event
.type
= WebKit::WebInputEvent::MouseWheel
;
143 webkit_event
.button
= WebKit::WebMouseEvent::ButtonNone
;
144 webkit_event
.modifiers
= EventFlagsToWebEventModifiers(event
->flags());
145 webkit_event
.timeStampSeconds
= event
->time_stamp().InSecondsF();
146 webkit_event
.hasPreciseScrollingDeltas
= true;
147 webkit_event
.deltaX
= event
->x_offset();
148 webkit_event
.wheelTicksX
= webkit_event
.deltaX
/ kPixelsPerTick
;
149 webkit_event
.deltaY
= event
->y_offset();
150 webkit_event
.wheelTicksY
= webkit_event
.deltaY
/ kPixelsPerTick
;
155 // NOTE: ui::ScrollEvent instances come from the touchpad.
156 WebKit::WebGestureEvent
MakeWebGestureEventFromAuraEvent(
157 ui::ScrollEvent
* event
) {
158 WebKit::WebGestureEvent webkit_event
;
160 switch (event
->type()) {
162 // TODO(sadrul || rjkroege): This will do touchscreen style scrolling in
163 // response to touchpad events. Currently, touchscreen and touchpad
164 // scrolls are the same. However, if the planned changes to touchscreen
165 // scrolling take place, this will no longer be so. If so, this needs to
167 webkit_event
.type
= WebKit::WebInputEvent::GestureScrollUpdate
;
168 webkit_event
.data
.scrollUpdate
.deltaX
= event
->x_offset();
169 webkit_event
.data
.scrollUpdate
.deltaY
= event
->y_offset();
171 case ui::ET_SCROLL_FLING_START
:
172 webkit_event
.type
= WebKit::WebInputEvent::GestureFlingStart
;
173 webkit_event
.data
.flingStart
.velocityX
= event
->x_offset();
174 webkit_event
.data
.flingStart
.velocityY
= event
->y_offset();
175 webkit_event
.data
.flingStart
.sourceDevice
=
176 WebKit::WebGestureEvent::Touchpad
;
178 case ui::ET_SCROLL_FLING_CANCEL
:
179 webkit_event
.type
= WebKit::WebInputEvent::GestureFlingCancel
;
182 NOTREACHED() << "Unknown gesture type: " << event
->type();
185 webkit_event
.modifiers
= EventFlagsToWebEventModifiers(event
->flags());
186 webkit_event
.timeStampSeconds
= event
->time_stamp().InSecondsF();
191 WebKit::WebKeyboardEvent
MakeWebKeyboardEventFromAuraEvent(
192 ui::KeyEvent
* event
) {
193 base::NativeEvent native_event
= event
->native_event();
194 WebKit::WebKeyboardEvent webkit_event
;
195 XKeyEvent
* native_key_event
= &native_event
->xkey
;
197 webkit_event
.timeStampSeconds
= event
->time_stamp().InSecondsF();
198 webkit_event
.modifiers
= EventFlagsToWebEventModifiers(event
->flags());
200 switch (native_event
->type
) {
202 webkit_event
.type
= event
->is_char() ? WebKit::WebInputEvent::Char
:
203 WebKit::WebInputEvent::RawKeyDown
;
206 webkit_event
.type
= WebKit::WebInputEvent::KeyUp
;
212 if (webkit_event
.modifiers
& WebKit::WebInputEvent::AltKey
)
213 webkit_event
.isSystemKey
= true;
215 webkit_event
.windowsKeyCode
= XKeyEventToWindowsKeyCode(native_key_event
);
216 webkit_event
.nativeKeyCode
= native_key_event
->keycode
;
218 if (webkit_event
.windowsKeyCode
== ui::VKEY_RETURN
)
219 webkit_event
.unmodifiedText
[0] = '\r';
221 webkit_event
.unmodifiedText
[0] = ui::GetCharacterFromXEvent(native_event
);
223 if (webkit_event
.modifiers
& WebKit::WebInputEvent::ControlKey
) {
224 webkit_event
.text
[0] =
226 webkit_event
.windowsKeyCode
,
227 webkit_event
.modifiers
& WebKit::WebInputEvent::ShiftKey
);
229 webkit_event
.text
[0] = webkit_event
.unmodifiedText
[0];
232 webkit_event
.setKeyIdentifierFromWindowsKeyCode();
234 // TODO: IsAutoRepeat/IsKeyPad?
239 } // namespace content