| 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 |