diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/web/WebInputEventFactoryGtk.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/web/WebInputEventFactoryGtk.cpp | 629 |
1 files changed, 0 insertions, 629 deletions
diff --git a/chromium/third_party/WebKit/Source/web/WebInputEventFactoryGtk.cpp b/chromium/third_party/WebKit/Source/web/WebInputEventFactoryGtk.cpp deleted file mode 100644 index 45450fdffff..00000000000 --- a/chromium/third_party/WebKit/Source/web/WebInputEventFactoryGtk.cpp +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (C) 2006-2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebInputEventFactory.h" - -#include "core/platform/chromium/KeyCodeConversion.h" -#include "platform/KeyboardCodes.h" - -#include "WebInputEvent.h" - -#include <gdk/gdk.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <stdlib.h> - -#include "wtf/Assertions.h" - -namespace { - -// For click count tracking. -static int gNumClicks = 0; -static GdkWindow* gLastClickEventWindow = 0; -static gint gLastClickTime = 0; -static gint gLastClickX = 0; -static gint gLastClickY = 0; -static blink::WebMouseEvent::Button gLastClickButton = blink::WebMouseEvent::ButtonNone; - -bool shouldForgetPreviousClick(GdkWindow* window, gint time, gint x, gint y) -{ - static GtkSettings* settings = gtk_settings_get_default(); - - if (window != gLastClickEventWindow) - return true; - - gint doubleClickTime = 250; - gint doubleClickDistance = 5; - g_object_get(G_OBJECT(settings), - "gtk-double-click-time", &doubleClickTime, - "gtk-double-click-distance", &doubleClickDistance, NULL); - return (time - gLastClickTime) > doubleClickTime - || abs(x - gLastClickX) > doubleClickDistance - || abs(y - gLastClickY) > doubleClickDistance; -} - -void resetClickCountState() -{ - gNumClicks = 0; - gLastClickEventWindow = 0; - gLastClickTime = 0; - gLastClickX = 0; - gLastClickY = 0; - gLastClickButton = blink::WebMouseEvent::ButtonNone; -} - -bool isKeyPadKeyval(guint keyval) -{ - // Keypad keyvals all fall into one range. - return keyval >= GDK_KP_Space && keyval <= GDK_KP_9; -} - -} // namespace - -namespace blink { - -static double gdkEventTimeToWebEventTime(guint32 time) -{ - // Convert from time in ms to time in sec. - return time / 1000.0; -} - -static int gdkStateToWebEventModifiers(guint state) -{ - int modifiers = 0; - if (state & GDK_SHIFT_MASK) - modifiers |= WebInputEvent::ShiftKey; - if (state & GDK_CONTROL_MASK) - modifiers |= WebInputEvent::ControlKey; - if (state & GDK_MOD1_MASK) - modifiers |= WebInputEvent::AltKey; - if (state & GDK_META_MASK) - modifiers |= WebInputEvent::MetaKey; - if (state & GDK_BUTTON1_MASK) - modifiers |= WebInputEvent::LeftButtonDown; - if (state & GDK_BUTTON2_MASK) - modifiers |= WebInputEvent::MiddleButtonDown; - if (state & GDK_BUTTON3_MASK) - modifiers |= WebInputEvent::RightButtonDown; - if (state & GDK_LOCK_MASK) - modifiers |= WebInputEvent::CapsLockOn; - if (state & GDK_MOD2_MASK) - modifiers |= WebInputEvent::NumLockOn; - return modifiers; -} - -static int gdkEventToWindowsKeyCode(const GdkEventKey* event) -{ - static const unsigned int hardwareCodeToGDKKeyval[] = { - 0, // 0x00: - 0, // 0x01: - 0, // 0x02: - 0, // 0x03: - 0, // 0x04: - 0, // 0x05: - 0, // 0x06: - 0, // 0x07: - 0, // 0x08: - 0, // 0x09: GDK_Escape - GDK_1, // 0x0A: GDK_1 - GDK_2, // 0x0B: GDK_2 - GDK_3, // 0x0C: GDK_3 - GDK_4, // 0x0D: GDK_4 - GDK_5, // 0x0E: GDK_5 - GDK_6, // 0x0F: GDK_6 - GDK_7, // 0x10: GDK_7 - GDK_8, // 0x11: GDK_8 - GDK_9, // 0x12: GDK_9 - GDK_0, // 0x13: GDK_0 - GDK_minus, // 0x14: GDK_minus - GDK_equal, // 0x15: GDK_equal - 0, // 0x16: GDK_BackSpace - 0, // 0x17: GDK_Tab - GDK_q, // 0x18: GDK_q - GDK_w, // 0x19: GDK_w - GDK_e, // 0x1A: GDK_e - GDK_r, // 0x1B: GDK_r - GDK_t, // 0x1C: GDK_t - GDK_y, // 0x1D: GDK_y - GDK_u, // 0x1E: GDK_u - GDK_i, // 0x1F: GDK_i - GDK_o, // 0x20: GDK_o - GDK_p, // 0x21: GDK_p - GDK_bracketleft, // 0x22: GDK_bracketleft - GDK_bracketright, // 0x23: GDK_bracketright - 0, // 0x24: GDK_Return - 0, // 0x25: GDK_Control_L - GDK_a, // 0x26: GDK_a - GDK_s, // 0x27: GDK_s - GDK_d, // 0x28: GDK_d - GDK_f, // 0x29: GDK_f - GDK_g, // 0x2A: GDK_g - GDK_h, // 0x2B: GDK_h - GDK_j, // 0x2C: GDK_j - GDK_k, // 0x2D: GDK_k - GDK_l, // 0x2E: GDK_l - GDK_semicolon, // 0x2F: GDK_semicolon - GDK_apostrophe, // 0x30: GDK_apostrophe - GDK_grave, // 0x31: GDK_grave - 0, // 0x32: GDK_Shift_L - GDK_backslash, // 0x33: GDK_backslash - GDK_z, // 0x34: GDK_z - GDK_x, // 0x35: GDK_x - GDK_c, // 0x36: GDK_c - GDK_v, // 0x37: GDK_v - GDK_b, // 0x38: GDK_b - GDK_n, // 0x39: GDK_n - GDK_m, // 0x3A: GDK_m - GDK_comma, // 0x3B: GDK_comma - GDK_period, // 0x3C: GDK_period - GDK_slash, // 0x3D: GDK_slash - 0, // 0x3E: GDK_Shift_R - 0, // 0x3F: - 0, // 0x40: - 0, // 0x41: - 0, // 0x42: - 0, // 0x43: - 0, // 0x44: - 0, // 0x45: - 0, // 0x46: - 0, // 0x47: - 0, // 0x48: - 0, // 0x49: - 0, // 0x4A: - 0, // 0x4B: - 0, // 0x4C: - 0, // 0x4D: - 0, // 0x4E: - 0, // 0x4F: - 0, // 0x50: - 0, // 0x51: - 0, // 0x52: - 0, // 0x53: - 0, // 0x54: - 0, // 0x55: - 0, // 0x56: - 0, // 0x57: - 0, // 0x58: - 0, // 0x59: - 0, // 0x5A: - 0, // 0x5B: - 0, // 0x5C: - 0, // 0x5D: - 0, // 0x5E: - 0, // 0x5F: - 0, // 0x60: - 0, // 0x61: - 0, // 0x62: - 0, // 0x63: - 0, // 0x64: - 0, // 0x65: - 0, // 0x66: - 0, // 0x67: - 0, // 0x68: - 0, // 0x69: - 0, // 0x6A: - 0, // 0x6B: - 0, // 0x6C: - 0, // 0x6D: - 0, // 0x6E: - 0, // 0x6F: - 0, // 0x70: - 0, // 0x71: - 0, // 0x72: - GDK_Super_L, // 0x73: GDK_Super_L - GDK_Super_R, // 0x74: GDK_Super_R - }; - - // |windowsKeyCode| has to include a valid virtual-key code even when we - // use non-US layouts, e.g. even when we type an 'A' key of a US keyboard - // on the Hebrew layout, |windowsKeyCode| should be VK_A. - // On the other hand, |event->keyval| value depends on the current - // GdkKeymap object, i.e. when we type an 'A' key of a US keyboard on - // the Hebrew layout, |event->keyval| becomes GDK_hebrew_shin and this - // WebCore::windowsKeyCodeForKeyEvent() call returns 0. - // To improve compatibilty with Windows, we use |event->hardware_keycode| - // for retrieving its Windows key-code for the keys when the - // WebCore::windowsKeyCodeForEvent() call returns 0. - // We shouldn't use |event->hardware_keycode| for keys that GdkKeymap - // objects cannot change because |event->hardware_keycode| doesn't change - // even when we change the layout options, e.g. when we swap a control - // key and a caps-lock key, GTK doesn't swap their - // |event->hardware_keycode| values but swap their |event->keyval| values. - int windowsKeyCode = WebCore::windowsKeyCodeForKeyEvent(event->keyval); - if (windowsKeyCode) - return windowsKeyCode; - - const int tableSize = sizeof(hardwareCodeToGDKKeyval) / sizeof(hardwareCodeToGDKKeyval[0]); - if (event->hardware_keycode < tableSize) { - int keyval = hardwareCodeToGDKKeyval[event->hardware_keycode]; - if (keyval) - return WebCore::windowsKeyCodeForKeyEvent(keyval); - } - - // This key is one that keyboard-layout drivers cannot change. - // Use |event->keyval| to retrieve its |windowsKeyCode| value. - return WebCore::windowsKeyCodeForKeyEvent(event->keyval); -} - -// Normalizes event->state to make it Windows/Mac compatible. Since the way -// of setting modifier mask on X is very different than Windows/Mac as shown -// in http://crbug.com/127142#c8, the normalization is necessary. -static guint normalizeEventState(const GdkEventKey* event) -{ - guint mask = 0; - switch (gdkEventToWindowsKeyCode(event)) { - case WebCore::VKEY_CONTROL: - case WebCore::VKEY_LCONTROL: - case WebCore::VKEY_RCONTROL: - mask = GDK_CONTROL_MASK; - break; - case WebCore::VKEY_SHIFT: - case WebCore::VKEY_LSHIFT: - case WebCore::VKEY_RSHIFT: - mask = GDK_SHIFT_MASK; - break; - case WebCore::VKEY_MENU: - case WebCore::VKEY_LMENU: - case WebCore::VKEY_RMENU: - mask = GDK_MOD1_MASK; - break; - case WebCore::VKEY_CAPITAL: - mask = GDK_LOCK_MASK; - break; - default: - return event->state; - } - if (event->type == GDK_KEY_PRESS) - return event->state | mask; - return event->state & ~mask; -} - -// Gets the corresponding control character of a specified key code. See: -// http://en.wikipedia.org/wiki/Control_characters -// We emulate Windows behavior here. -static WebUChar getControlCharacter(int windowsKeyCode, bool shift) -{ - if (windowsKeyCode >= WebCore::VKEY_A && windowsKeyCode <= WebCore::VKEY_Z) { - // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A - return windowsKeyCode - WebCore::VKEY_A + 1; - } - if (shift) { - // following graphics chars require shift key to input. - switch (windowsKeyCode) { - // ctrl-@ maps to \x00 (Null byte) - case WebCore::VKEY_2: - return 0; - // ctrl-^ maps to \x1E (Record separator, Information separator two) - case WebCore::VKEY_6: - return 0x1E; - // ctrl-_ maps to \x1F (Unit separator, Information separator one) - case WebCore::VKEY_OEM_MINUS: - return 0x1F; - // Returns 0 for all other keys to avoid inputting unexpected chars. - default: - return 0; - } - } else { - switch (windowsKeyCode) { - // ctrl-[ maps to \x1B (Escape) - case WebCore::VKEY_OEM_4: - return 0x1B; - // ctrl-\ maps to \x1C (File separator, Information separator four) - case WebCore::VKEY_OEM_5: - return 0x1C; - // ctrl-] maps to \x1D (Group separator, Information separator three) - case WebCore::VKEY_OEM_6: - return 0x1D; - // ctrl-Enter maps to \x0A (Line feed) - case WebCore::VKEY_RETURN: - return 0x0A; - // Returns 0 for all other keys to avoid inputting unexpected chars. - default: - return 0; - } - } -} - -// WebKeyboardEvent ----------------------------------------------------------- - -WebKeyboardEvent WebInputEventFactory::keyboardEvent(const GdkEventKey* event) -{ - WebKeyboardEvent result; - - result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time); - result.modifiers = gdkStateToWebEventModifiers(normalizeEventState(event)); - - switch (event->type) { - case GDK_KEY_RELEASE: - result.type = WebInputEvent::KeyUp; - break; - case GDK_KEY_PRESS: - result.type = WebInputEvent::RawKeyDown; - break; - default: - ASSERT_NOT_REACHED(); - } - - result.isSystemKey = WebInputEventFactory::isSystemKeyEvent(result); - - // The key code tells us which physical key was pressed (for example, the - // A key went down or up). It does not determine whether A should be lower - // or upper case. This is what text does, which should be the keyval. - int windowsKeyCode = gdkEventToWindowsKeyCode(event); - result.windowsKeyCode = WebKeyboardEvent::windowsKeyCodeWithoutLocation(windowsKeyCode); - result.modifiers |= WebKeyboardEvent::locationModifiersFromWindowsKeyCode(windowsKeyCode); - result.nativeKeyCode = event->hardware_keycode; - - if (result.windowsKeyCode == WebCore::VKEY_RETURN) - // We need to treat the enter key as a key press of character \r. This - // is apparently just how webkit handles it and what it expects. - result.unmodifiedText[0] = '\r'; - else - // FIXME: fix for non BMP chars - result.unmodifiedText[0] = - static_cast<WebUChar>(gdk_keyval_to_unicode(event->keyval)); - - // If ctrl key is pressed down, then control character shall be input. - if (result.modifiers & WebInputEvent::ControlKey) - result.text[0] = getControlCharacter( - result.windowsKeyCode, result.modifiers & WebInputEvent::ShiftKey); - else - result.text[0] = result.unmodifiedText[0]; - - result.setKeyIdentifierFromWindowsKeyCode(); - - // FIXME: Do we need to set IsAutoRepeat? - if (isKeyPadKeyval(event->keyval)) - result.modifiers |= WebInputEvent::IsKeyPad; - - return result; -} - -bool WebInputEventFactory::isSystemKeyEvent(const WebKeyboardEvent& event) -{ - // On Windows all keys with Alt modifier will be marked as system key. - // We keep the same behavior on Linux and everywhere non-Mac. - return event.modifiers & WebInputEvent::AltKey; -} - -WebKeyboardEvent WebInputEventFactory::keyboardEvent(wchar_t character, int state, double timeStampSeconds) -{ - // keyboardEvent(const GdkEventKey*) depends on the GdkEventKey object and - // it is hard to use/ it from signal handlers which don't use GdkEventKey - // objects (e.g. GtkIMContext signal handlers.) For such handlers, this - // function creates a WebInputEvent::Char event without using a - // GdkEventKey object. - WebKeyboardEvent result; - result.type = blink::WebInputEvent::Char; - result.timeStampSeconds = timeStampSeconds; - result.modifiers = gdkStateToWebEventModifiers(state); - result.windowsKeyCode = character; - result.nativeKeyCode = character; - result.text[0] = character; - result.unmodifiedText[0] = character; - - // According to MSDN: - // http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx - // Key events with Alt modifier and F10 are system key events. - // We just emulate this behavior. It's necessary to prevent webkit from - // processing keypress event generated by alt-d, etc. - // F10 is not special on Linux, so don't treat it as system key. - if (result.modifiers & WebInputEvent::AltKey) - result.isSystemKey = true; - - return result; -} - -// WebMouseEvent -------------------------------------------------------------- - -WebMouseEvent WebInputEventFactory::mouseEvent(const GdkEventButton* event) -{ - WebMouseEvent result; - - result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time); - - result.modifiers = gdkStateToWebEventModifiers(event->state); - result.x = static_cast<int>(event->x); - result.y = static_cast<int>(event->y); - result.windowX = result.x; - result.windowY = result.y; - result.globalX = static_cast<int>(event->x_root); - result.globalY = static_cast<int>(event->y_root); - result.clickCount = 0; - - switch (event->type) { - case GDK_BUTTON_PRESS: - result.type = WebInputEvent::MouseDown; - break; - case GDK_BUTTON_RELEASE: - result.type = WebInputEvent::MouseUp; - break; - case GDK_3BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - default: - ASSERT_NOT_REACHED(); - }; - - result.button = WebMouseEvent::ButtonNone; - if (event->button == 1) - result.button = WebMouseEvent::ButtonLeft; - else if (event->button == 2) - result.button = WebMouseEvent::ButtonMiddle; - else if (event->button == 3) - result.button = WebMouseEvent::ButtonRight; - - if (result.type == WebInputEvent::MouseDown) { - bool forgetPreviousClick = shouldForgetPreviousClick(event->window, event->time, event->x, event->y); - - if (!forgetPreviousClick && result.button == gLastClickButton) - ++gNumClicks; - else { - gNumClicks = 1; - - gLastClickEventWindow = event->window; - gLastClickX = event->x; - gLastClickY = event->y; - gLastClickButton = result.button; - } - gLastClickTime = event->time; - } - result.clickCount = gNumClicks; - - return result; -} - -WebMouseEvent WebInputEventFactory::mouseEvent(const GdkEventMotion* event) -{ - WebMouseEvent result; - - result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time); - result.modifiers = gdkStateToWebEventModifiers(event->state); - result.x = static_cast<int>(event->x); - result.y = static_cast<int>(event->y); - result.windowX = result.x; - result.windowY = result.y; - result.globalX = static_cast<int>(event->x_root); - result.globalY = static_cast<int>(event->y_root); - - switch (event->type) { - case GDK_MOTION_NOTIFY: - result.type = WebInputEvent::MouseMove; - break; - default: - ASSERT_NOT_REACHED(); - } - - result.button = WebMouseEvent::ButtonNone; - if (event->state & GDK_BUTTON1_MASK) - result.button = WebMouseEvent::ButtonLeft; - else if (event->state & GDK_BUTTON2_MASK) - result.button = WebMouseEvent::ButtonMiddle; - else if (event->state & GDK_BUTTON3_MASK) - result.button = WebMouseEvent::ButtonRight; - - if (shouldForgetPreviousClick(event->window, event->time, event->x, event->y)) - resetClickCountState(); - - return result; -} - -WebMouseEvent WebInputEventFactory::mouseEvent(const GdkEventCrossing* event) -{ - WebMouseEvent result; - - result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time); - result.modifiers = gdkStateToWebEventModifiers(event->state); - result.x = static_cast<int>(event->x); - result.y = static_cast<int>(event->y); - result.windowX = result.x; - result.windowY = result.y; - result.globalX = static_cast<int>(event->x_root); - result.globalY = static_cast<int>(event->y_root); - - switch (event->type) { - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - // Note that if we sent MouseEnter or MouseLeave to WebKit, it - // wouldn't work - they don't result in the proper JavaScript events. - // MouseMove does the right thing. - result.type = WebInputEvent::MouseMove; - break; - default: - ASSERT_NOT_REACHED(); - } - - result.button = WebMouseEvent::ButtonNone; - if (event->state & GDK_BUTTON1_MASK) - result.button = WebMouseEvent::ButtonLeft; - else if (event->state & GDK_BUTTON2_MASK) - result.button = WebMouseEvent::ButtonMiddle; - else if (event->state & GDK_BUTTON3_MASK) - result.button = WebMouseEvent::ButtonRight; - - if (shouldForgetPreviousClick(event->window, event->time, event->x, event->y)) - resetClickCountState(); - - return result; -} - -// WebMouseWheelEvent --------------------------------------------------------- - -WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(const GdkEventScroll* event) -{ - WebMouseWheelEvent result; - - result.type = WebInputEvent::MouseWheel; - result.button = WebMouseEvent::ButtonNone; - - result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time); - result.modifiers = gdkStateToWebEventModifiers(event->state); - result.x = static_cast<int>(event->x); - result.y = static_cast<int>(event->y); - result.windowX = result.x; - result.windowY = result.y; - result.globalX = static_cast<int>(event->x_root); - result.globalY = static_cast<int>(event->y_root); - - // How much should we scroll per mouse wheel event? - // - Windows uses 3 lines by default and obeys a system setting. - // - Mozilla has a pref that lets you either use the "system" number of lines - // to scroll, or lets the user override it. - // For the "system" number of lines, it appears they've hardcoded 3. - // See case NS_MOUSE_SCROLL in content/events/src/nsEventStateManager.cpp - // and InitMouseScrollEvent in widget/src/gtk2/nsCommonWidget.cpp . - // - Gtk makes the scroll amount a function of the size of the scroll bar, - // which is not available to us here. - // Instead, we pick a number that empirically matches Firefox's behavior. - static const float scrollbarPixelsPerTick = 160.0f / 3.0f; - - switch (event->direction) { - case GDK_SCROLL_UP: - result.deltaY = scrollbarPixelsPerTick; - result.wheelTicksY = 1; - break; - case GDK_SCROLL_DOWN: - result.deltaY = -scrollbarPixelsPerTick; - result.wheelTicksY = -1; - break; - case GDK_SCROLL_LEFT: - result.deltaX = scrollbarPixelsPerTick; - result.wheelTicksX = 1; - break; - case GDK_SCROLL_RIGHT: - result.deltaX = -scrollbarPixelsPerTick; - result.wheelTicksX = -1; - break; - } - - return result; -} - -} // namespace blink |