OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Portions based heavily on: | 5 // Portions based heavily on: |
6 // third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.cpp | 6 // third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.cpp |
7 // | 7 // |
8 /* | 8 /* |
9 * Copyright (C) 2006-2011 Google Inc. All rights reserved. | 9 * Copyright (C) 2006-2011 Google Inc. All rights reserved. |
10 * | 10 * |
(...skipping 24 matching lines...) Expand all Loading... |
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 */ | 36 */ |
37 | 37 |
38 #include "content/browser/renderer_host/web_input_event_aura.h" | 38 #include "content/browser/renderer_host/web_input_event_aura.h" |
39 | 39 |
40 #include <cstdlib> | 40 #include <cstdlib> |
41 #include <X11/Xlib.h> | 41 #include <X11/Xlib.h> |
42 | 42 |
43 #include "base/event_types.h" | 43 #include "base/event_types.h" |
44 #include "base/logging.h" | 44 #include "base/logging.h" |
| 45 #include "ui/aura/event.h" |
| 46 #include "ui/base/events.h" |
45 #include "ui/base/keycodes/keyboard_codes.h" | 47 #include "ui/base/keycodes/keyboard_codes.h" |
| 48 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
46 | 49 |
47 namespace content { | 50 namespace content { |
48 | 51 |
49 // chromium WebKit does not provide a WebInputEventFactory for X11, so we have | 52 // chromium WebKit does not provide a WebInputEventFactory for X11, so we have |
50 // to do the work here ourselves. | 53 // to do the work here ourselves. |
51 | 54 |
52 namespace { | 55 namespace { |
53 | 56 |
54 double XEventTimeToWebEventTime(Time time) { | 57 double XEventTimeToWebEventTime(Time time) { |
55 // Convert from time in ms to time in s. | 58 // Convert from time in ms to time in s. |
56 return time / 1000.0; | 59 return time / 1000.0; |
57 } | 60 } |
58 | 61 |
| 62 int EventFlagsToWebEventModifiers(int flags) { |
| 63 int modifiers = 0; |
| 64 if (flags & ui::EF_SHIFT_DOWN) |
| 65 modifiers |= WebKit::WebInputEvent::ShiftKey; |
| 66 if (flags & ui::EF_CONTROL_DOWN) |
| 67 modifiers |= WebKit::WebInputEvent::ControlKey; |
| 68 if (flags & ui::EF_ALT_DOWN) |
| 69 modifiers |= WebKit::WebInputEvent::AltKey; |
| 70 // TODO(beng): MetaKey/META_MASK |
| 71 if (flags & ui::EF_LEFT_BUTTON_DOWN) |
| 72 modifiers |= WebKit::WebInputEvent::LeftButtonDown; |
| 73 if (flags & ui::EF_MIDDLE_BUTTON_DOWN) |
| 74 modifiers |= WebKit::WebInputEvent::MiddleButtonDown; |
| 75 if (flags & ui::EF_RIGHT_BUTTON_DOWN) |
| 76 modifiers |= WebKit::WebInputEvent::RightButtonDown; |
| 77 if (flags & ui::EF_CAPS_LOCK_DOWN) |
| 78 modifiers |= WebKit::WebInputEvent::CapsLockOn; |
| 79 return modifiers; |
| 80 } |
| 81 |
59 int XStateToWebEventModifiers(unsigned int state) { | 82 int XStateToWebEventModifiers(unsigned int state) { |
60 int modifiers = 0; | 83 int modifiers = 0; |
61 if (state & ShiftMask) | 84 if (state & ShiftMask) |
62 modifiers |= WebKit::WebInputEvent::ShiftKey; | 85 modifiers |= WebKit::WebInputEvent::ShiftKey; |
63 if (state & ControlMask) | 86 if (state & ControlMask) |
64 modifiers |= WebKit::WebInputEvent::ControlKey; | 87 modifiers |= WebKit::WebInputEvent::ControlKey; |
65 if (state & Mod1Mask) | 88 if (state & Mod1Mask) |
66 modifiers |= WebKit::WebInputEvent::AltKey; | 89 modifiers |= WebKit::WebInputEvent::AltKey; |
67 // TODO(beng): MetaKey/META_MASK | 90 // TODO(beng): MetaKey/META_MASK |
68 if (state & Button1Mask) | 91 if (state & Button1Mask) |
69 modifiers |= WebKit::WebInputEvent::LeftButtonDown; | 92 modifiers |= WebKit::WebInputEvent::LeftButtonDown; |
70 if (state & Button2Mask) | 93 if (state & Button2Mask) |
71 modifiers |= WebKit::WebInputEvent::MiddleButtonDown; | 94 modifiers |= WebKit::WebInputEvent::MiddleButtonDown; |
72 if (state & Button3Mask) | 95 if (state & Button3Mask) |
73 modifiers |= WebKit::WebInputEvent::RightButtonDown; | 96 modifiers |= WebKit::WebInputEvent::RightButtonDown; |
74 if (state & LockMask) | 97 if (state & LockMask) |
75 modifiers |= WebKit::WebInputEvent::CapsLockOn; | 98 modifiers |= WebKit::WebInputEvent::CapsLockOn; |
76 if (state & Mod2Mask) | 99 if (state & Mod2Mask) |
77 modifiers |= WebKit::WebInputEvent::NumLockOn; | 100 modifiers |= WebKit::WebInputEvent::NumLockOn; |
78 return modifiers; | 101 return modifiers; |
79 } | 102 } |
80 | 103 |
81 int XKeyEventToWindowsKeyCode(XKeyEvent* event) { | 104 int XKeyEventToWindowsKeyCode(XKeyEvent* event) { |
82 // TODO(beng): | 105 return ui::KeyboardCodeFromXKeyEvent((XEvent*)event); |
83 return 0; | |
84 } | 106 } |
85 | 107 |
86 // From | 108 // From |
87 // third_party/WebKit/Source/WebKit/chromium/src/gtk/WebInputEventFactory.cpp: | 109 // third_party/WebKit/Source/WebKit/chromium/src/gtk/WebInputEventFactory.cpp: |
88 WebKit::WebUChar GetControlCharacter(int windows_key_code, bool shift) { | 110 WebKit::WebUChar GetControlCharacter(int windows_key_code, bool shift) { |
89 if (windows_key_code >= ui::VKEY_A && | 111 if (windows_key_code >= ui::VKEY_A && |
90 windows_key_code <= ui::VKEY_Z) { | 112 windows_key_code <= ui::VKEY_Z) { |
91 // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A | 113 // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A |
92 return windows_key_code - ui::VKEY_A + 1; | 114 return windows_key_code - ui::VKEY_A + 1; |
93 } | 115 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 return WebKit::WebMouseEvent::ButtonLeft; | 170 return WebKit::WebMouseEvent::ButtonLeft; |
149 if (state & Button2MotionMask) | 171 if (state & Button2MotionMask) |
150 return WebKit::WebMouseEvent::ButtonMiddle; | 172 return WebKit::WebMouseEvent::ButtonMiddle; |
151 if (state & Button3MotionMask) | 173 if (state & Button3MotionMask) |
152 return WebKit::WebMouseEvent::ButtonRight; | 174 return WebKit::WebMouseEvent::ButtonRight; |
153 return WebKit::WebMouseEvent::ButtonNone; | 175 return WebKit::WebMouseEvent::ButtonNone; |
154 } | 176 } |
155 | 177 |
156 // We have to count clicks (for double-clicks) manually. | 178 // We have to count clicks (for double-clicks) manually. |
157 unsigned int g_num_clicks = 0; | 179 unsigned int g_num_clicks = 0; |
158 ::Window* g_last_click_window = NULL; | 180 double g_last_click_time = 0.0; |
159 Time g_last_click_time = 0; | |
160 int g_last_click_x = 0; | 181 int g_last_click_x = 0; |
161 int g_last_click_y = 0; | 182 int g_last_click_y = 0; |
162 WebKit::WebMouseEvent::Button g_last_click_button = | 183 WebKit::WebMouseEvent::Button g_last_click_button = |
163 WebKit::WebMouseEvent::ButtonNone; | 184 WebKit::WebMouseEvent::ButtonNone; |
164 | 185 |
165 bool ShouldForgetPreviousClick(::Window* window, Time time, int x, int y) { | 186 bool ShouldForgetPreviousClick(double time, int x, int y) { |
166 if (window != g_last_click_window) | 187 const double double_click_time = 0.250; // in seconds |
167 return true; | |
168 | |
169 const Time double_click_time = 250; | |
170 const int double_click_distance = 5; | 188 const int double_click_distance = 5; |
171 return (time - g_last_click_time) > double_click_time | 189 return (time - g_last_click_time) > double_click_time || |
172 || std::abs(x - g_last_click_x) > double_click_distance | 190 std::abs(x - g_last_click_x) > double_click_distance || |
173 || std::abs(y - g_last_click_y) > double_click_distance; | 191 std::abs(y - g_last_click_y) > double_click_distance; |
174 } | 192 } |
175 | 193 |
176 void ResetClickCountState() { | 194 void ResetClickCountState() { |
177 g_num_clicks = 0; | 195 g_num_clicks = 0; |
178 g_last_click_window = NULL; | 196 g_last_click_time = 0.0; |
179 g_last_click_time = 0; | |
180 g_last_click_x = 0; | 197 g_last_click_x = 0; |
181 g_last_click_y = 0; | 198 g_last_click_y = 0; |
182 g_last_click_button = WebKit::WebMouseEvent::ButtonNone; | 199 g_last_click_button = WebKit::WebMouseEvent::ButtonNone; |
183 } | 200 } |
184 | 201 |
185 void InitWebKitEventFromButtonEvent(WebKit::WebMouseEvent* webkit_event, | 202 } // namespace |
186 XButtonEvent* native_event) { | |
187 webkit_event->modifiers = XStateToWebEventModifiers(native_event->state); | |
188 webkit_event->timeStampSeconds = XEventTimeToWebEventTime(native_event->time); | |
189 | 203 |
190 webkit_event->x = native_event->x; | 204 WebKit::WebMouseEvent MakeWebMouseEventFromAuraEvent(aura::MouseEvent* event) { |
191 webkit_event->y = native_event->y; | 205 WebKit::WebMouseEvent webkit_event; |
192 webkit_event->windowX = webkit_event->x; | |
193 webkit_event->windowY = webkit_event->y; | |
194 webkit_event->globalX = native_event->x_root; | |
195 webkit_event->globalY = native_event->y_root; | |
196 | 206 |
197 switch (native_event->type) { | 207 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags()); |
198 case ButtonPress: | 208 webkit_event.timeStampSeconds = event->time_stamp().ToDoubleT(); |
199 webkit_event->type = WebKit::WebInputEvent::MouseDown; | 209 |
200 webkit_event->button = ButtonFromXButton(native_event->button); | 210 webkit_event.button = WebKit::WebMouseEvent::ButtonNone; |
201 if (!ShouldForgetPreviousClick(&native_event->window, | 211 if (event->flags() & ui::EF_LEFT_BUTTON_DOWN) |
202 native_event->time, | 212 webkit_event.button = WebKit::WebMouseEvent::ButtonLeft; |
203 native_event->x, | 213 if (event->flags() & ui::EF_MIDDLE_BUTTON_DOWN) |
204 native_event->y) && | 214 webkit_event.button = WebKit::WebMouseEvent::ButtonMiddle; |
205 webkit_event->button == g_last_click_button) { | 215 if (event->flags() & ui::EF_RIGHT_BUTTON_DOWN) |
| 216 webkit_event.button = WebKit::WebMouseEvent::ButtonRight; |
| 217 |
| 218 switch (event->type()) { |
| 219 case ui::ET_MOUSE_PRESSED: |
| 220 webkit_event.type = WebKit::WebInputEvent::MouseDown; |
| 221 if (!ShouldForgetPreviousClick(event->time_stamp().ToDoubleT(), |
| 222 event->location().x(), event->location().y()) && |
| 223 webkit_event.button == g_last_click_button) { |
206 ++g_num_clicks; | 224 ++g_num_clicks; |
207 } else { | 225 } else { |
208 g_num_clicks = 1; | 226 g_num_clicks = 1; |
209 g_last_click_window = &native_event->window; | 227 g_last_click_time = event->time_stamp().ToDoubleT(); |
210 g_last_click_x = native_event->x; | 228 g_last_click_x = event->location().x(); |
211 g_last_click_y = native_event->y; | 229 g_last_click_y = event->location().y(); |
212 g_last_click_button = webkit_event->button; | 230 g_last_click_button = webkit_event.button; |
213 } | 231 } |
| 232 webkit_event.clickCount = g_num_clicks; |
214 break; | 233 break; |
215 case ButtonRelease: | 234 case ui::ET_MOUSE_RELEASED: |
216 webkit_event->type = WebKit::WebInputEvent::MouseUp; | 235 webkit_event.type = WebKit::WebInputEvent::MouseUp; |
217 webkit_event->button = ButtonFromXButton(native_event->button); | 236 break; |
| 237 case ui::ET_MOUSE_ENTERED: |
| 238 case ui::ET_MOUSE_EXITED: |
| 239 case ui::ET_MOUSE_MOVED: |
| 240 case ui::ET_MOUSE_DRAGGED: |
| 241 webkit_event.type = WebKit::WebInputEvent::MouseMove; |
| 242 if (ShouldForgetPreviousClick(event->time_stamp().ToDoubleT(), |
| 243 event->location().x(), event->location().y())) |
| 244 ResetClickCountState(); |
218 break; | 245 break; |
219 default: | 246 default: |
220 NOTREACHED(); | 247 NOTIMPLEMENTED() << "Received unexpected event: " << event->type(); |
221 break; | 248 break; |
222 } | 249 } |
223 webkit_event->clickCount = g_num_clicks; | |
224 } | |
225 | 250 |
226 void InitWebKitEventFromMotionEvent(WebKit::WebMouseEvent* webkit_event, | |
227 XMotionEvent* native_event) { | |
228 webkit_event->modifiers = XStateToWebEventModifiers(native_event->state); | |
229 webkit_event->timeStampSeconds = XEventTimeToWebEventTime(native_event->time); | |
230 | |
231 webkit_event->x = native_event->x; | |
232 webkit_event->y = native_event->y; | |
233 webkit_event->windowX = webkit_event->x; | |
234 webkit_event->windowY = webkit_event->y; | |
235 webkit_event->globalX = native_event->x_root; | |
236 webkit_event->globalY = native_event->y_root; | |
237 | |
238 webkit_event->type = WebKit::WebInputEvent::MouseMove; | |
239 webkit_event->button = ButtonFromXState(native_event->state); | |
240 if (ShouldForgetPreviousClick(&native_event->window, | |
241 native_event->time, | |
242 native_event->x, | |
243 native_event->y)) { | |
244 ResetClickCountState(); | |
245 } | |
246 } | |
247 | |
248 } // namespace | |
249 | |
250 WebKit::WebMouseEvent MakeUntranslatedWebMouseEventFromNativeEvent( | |
251 base::NativeEvent native_event) { | |
252 WebKit::WebMouseEvent webkit_event; | |
253 | |
254 // In X, button and mouse movement events are different event types that | |
255 // require different handling. | |
256 // TODO(sadrul): Add support for XInput2 events. | |
257 switch (native_event->type) { | |
258 case ButtonPress: | |
259 case ButtonRelease: | |
260 InitWebKitEventFromButtonEvent(&webkit_event, &native_event->xbutton); | |
261 break; | |
262 case MotionNotify: | |
263 InitWebKitEventFromMotionEvent(&webkit_event, &native_event->xmotion); | |
264 break; | |
265 default: | |
266 NOTREACHED(); | |
267 break; | |
268 } | |
269 return webkit_event; | 251 return webkit_event; |
270 } | 252 } |
271 | 253 |
272 WebKit::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent( | 254 WebKit::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent( |
273 base::NativeEvent native_event) { | 255 base::NativeEvent native_event) { |
274 WebKit::WebKeyboardEvent webkit_event; | 256 WebKit::WebKeyboardEvent webkit_event; |
275 XKeyEvent* native_key_event = &native_event->xkey; | 257 XKeyEvent* native_key_event = &native_event->xkey; |
276 | 258 |
277 webkit_event.timeStampSeconds = | 259 webkit_event.timeStampSeconds = |
278 XEventTimeToWebEventTime(native_key_event->time); | 260 XEventTimeToWebEventTime(native_key_event->time); |
(...skipping 13 matching lines...) Expand all Loading... |
292 if (webkit_event.modifiers & WebKit::WebInputEvent::AltKey) | 274 if (webkit_event.modifiers & WebKit::WebInputEvent::AltKey) |
293 webkit_event.isSystemKey = true; | 275 webkit_event.isSystemKey = true; |
294 | 276 |
295 webkit_event.windowsKeyCode = XKeyEventToWindowsKeyCode(native_key_event); | 277 webkit_event.windowsKeyCode = XKeyEventToWindowsKeyCode(native_key_event); |
296 webkit_event.nativeKeyCode = native_key_event->keycode; | 278 webkit_event.nativeKeyCode = native_key_event->keycode; |
297 | 279 |
298 if (webkit_event.windowsKeyCode == ui::VKEY_RETURN) { | 280 if (webkit_event.windowsKeyCode == ui::VKEY_RETURN) { |
299 webkit_event.unmodifiedText[0] = '\r'; | 281 webkit_event.unmodifiedText[0] = '\r'; |
300 } else { | 282 } else { |
301 webkit_event.unmodifiedText[0] = | 283 webkit_event.unmodifiedText[0] = |
302 static_cast<WebKit::WebUChar>(native_key_event->keycode); | 284 ui::DefaultXKeysymFromHardwareKeycode(native_key_event->keycode); |
303 } | 285 } |
304 | 286 |
305 if (webkit_event.modifiers & WebKit::WebInputEvent::ControlKey) { | 287 if (webkit_event.modifiers & WebKit::WebInputEvent::ControlKey) { |
306 webkit_event.text[0] = | 288 webkit_event.text[0] = |
307 GetControlCharacter( | 289 GetControlCharacter( |
308 webkit_event.windowsKeyCode, | 290 webkit_event.windowsKeyCode, |
309 webkit_event.modifiers & WebKit::WebInputEvent::ShiftKey); | 291 webkit_event.modifiers & WebKit::WebInputEvent::ShiftKey); |
310 } else { | 292 } else { |
311 webkit_event.text[0] = webkit_event.unmodifiedText[0]; | 293 webkit_event.text[0] = webkit_event.unmodifiedText[0]; |
312 } | 294 } |
313 | 295 |
314 webkit_event.setKeyIdentifierFromWindowsKeyCode(); | 296 webkit_event.setKeyIdentifierFromWindowsKeyCode(); |
315 | 297 |
316 // TODO: IsAutoRepeat/IsKeyPad? | 298 // TODO: IsAutoRepeat/IsKeyPad? |
317 | 299 |
318 return webkit_event; | 300 return webkit_event; |
319 } | 301 } |
320 | 302 |
321 } // namespace content | 303 } // namespace content |
OLD | NEW |