181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch/*
281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved.
381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2011 Igalia S.L.
581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *
681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Redistribution and use in source and binary forms, with or without
781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * modification, are permitted provided that the following conditions
881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * are met:
981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * 1. Redistributions of source code must retain the above copyright
1081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *    notice, this list of conditions and the following disclaimer.
1181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright
1281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *    notice, this list of conditions and the following disclaimer in the
1381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *    documentation and/or other materials provided with the distribution.
1481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *
1581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
2681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch */
2781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "config.h"
2981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "WebEventFactory.h"
3081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
312bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "GtkVersioning.h"
3281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "PlatformKeyboardEvent.h"
3381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "Scrollbar.h"
3481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "WindowsKeyboardCodes.h"
3581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <gdk/gdk.h>
3681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <gdk/gdkkeysyms.h>
3781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <wtf/ASCIICType.h>
3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
3981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochusing namespace WebCore;
4081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochnamespace WebKit {
4281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline bool isGdkKeyCodeFromKeyPad(unsigned keyval)
4481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
452bde8e466a4451c7319e3a072d118917957d6554Steve Block    return keyval >= GDK_KP_Space && keyval <= GDK_KP_9;
4681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
4781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline WebEvent::Modifiers modifiersForEvent(const GdkEvent* event)
4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
5081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    unsigned modifiers = 0;
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    GdkModifierType state;
5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(gdk_event_get_state(event, &state));
5481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (state & GDK_CONTROL_MASK)
5681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        modifiers |= WebEvent::ControlKey;
5781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (state & GDK_SHIFT_MASK)
5881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        modifiers |= WebEvent::ShiftKey;
5981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (state & GDK_MOD1_MASK)
6081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        modifiers |= WebEvent::AltKey;
6181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (state & GDK_META_MASK)
6281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        modifiers |= WebEvent::MetaKey;
6381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return static_cast<WebEvent::Modifiers>(modifiers);
6581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
6681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline WebMouseEvent::Button buttonForEvent(GdkEvent* event)
6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
6981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    unsigned button = 0;
7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    switch (event->type) {
7281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_MOTION_NOTIFY:
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        button = WebMouseEvent::NoButton;
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (event->motion.state & GDK_BUTTON1_MASK)
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            button = WebMouseEvent::LeftButton;
7681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else if (event->motion.state & GDK_BUTTON2_MASK)
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            button = WebMouseEvent::MiddleButton;
7881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else if (event->motion.state & GDK_BUTTON3_MASK)
7981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            button = WebMouseEvent::RightButton;
8081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
8181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_BUTTON_PRESS:
8281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_2BUTTON_PRESS:
8381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_3BUTTON_PRESS:
8481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_BUTTON_RELEASE:
8581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (event->button.button == 1)
8681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            button = WebMouseEvent::LeftButton;
8781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else if (event->button.button == 2)
8881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            button = WebMouseEvent::MiddleButton;
8981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else if (event->button.button == 3)
9081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            button = WebMouseEvent::RightButton;
9181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
9281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    default:
9381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT_NOT_REACHED();
9481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
9581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return static_cast<WebMouseEvent::Button>(button);
9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
9881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochWebMouseEvent WebEventFactory::createWebMouseEvent(GdkEvent *event, int currentClickCount)
10081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
10181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    double x, y, xRoot, yRoot;
10281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    gdk_event_get_coords(event, &x, &y);
10381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    gdk_event_get_root_coords(event, &xRoot, &yRoot);
10481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
10581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    WebEvent::Type type = static_cast<WebEvent::Type>(0);
10681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    switch (event->type) {
10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_MOTION_NOTIFY:
10881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        type = WebEvent::MouseMove;
10981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
11081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_BUTTON_PRESS:
11181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_2BUTTON_PRESS:
11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_3BUTTON_PRESS:
11381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        type = WebEvent::MouseDown;
11481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_BUTTON_RELEASE:
11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        type = WebEvent::MouseUp;
11781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    default :
11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT_NOT_REACHED();
12081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
12181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
12281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return WebMouseEvent(type,
12381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         buttonForEvent(event),
12481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         IntPoint(x, y),
12581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         IntPoint(xRoot, yRoot),
12681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         0 /* deltaX */,
12781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         0 /* deltaY */,
12881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         0 /* deltaZ */,
12981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         currentClickCount,
13081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         static_cast<WebEvent::Modifiers>(0),
13181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         gdk_event_get_time(event));
13281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
13381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
13481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochWebWheelEvent WebEventFactory::createWebWheelEvent(GdkEventScroll* scrollEvent)
13581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
13681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    GdkEvent* event(reinterpret_cast<GdkEvent*>(scrollEvent));
13781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    double x, y, xRoot, yRoot;
13881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    gdk_event_get_coords(event, &x, &y);
13981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    gdk_event_get_root_coords(event, &xRoot, &yRoot);
14081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatSize wheelTicks;
14281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    switch (scrollEvent->direction) {
14381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_SCROLL_UP:
14481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        wheelTicks = FloatSize(0, 1);
14581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
14681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_SCROLL_DOWN:
14781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        wheelTicks = FloatSize(0, -1);
14881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
14981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_SCROLL_LEFT:
15081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        wheelTicks = FloatSize(1, 0);
15181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
15281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    case GDK_SCROLL_RIGHT:
15381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        wheelTicks = FloatSize(-1, 0);
15481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        break;
15581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    default:
15681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT_NOT_REACHED();
15781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
15881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // FIXME: [GTK] Add a setting to change the pixels per line used for scrolling
16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // https://bugs.webkit.org/show_bug.cgi?id=54826
16181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    float step = static_cast<float>(Scrollbar::pixelsPerLineStep());
16281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatSize delta(wheelTicks.width() * step, wheelTicks.height() * step);
16381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
16481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return WebWheelEvent(WebEvent::Wheel,
16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         IntPoint(x, y),
16681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         IntPoint(xRoot, yRoot),
16781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         delta,
16881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         wheelTicks,
16981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         WebWheelEvent::ScrollByPixelWheelEvent,
17081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         modifiersForEvent(event),
17181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                         gdk_event_get_time(event));
17281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
17381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
17481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochWebKeyboardEvent WebEventFactory::createWebKeyboardEvent(const GdkEventKey* event)
17581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
17681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return WebKeyboardEvent((event->type == GDK_KEY_RELEASE) ? WebEvent::KeyUp : WebEvent::KeyDown,
17781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            PlatformKeyboardEvent::singleCharacterString(event->keyval),
17881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            PlatformKeyboardEvent::singleCharacterString(event->keyval),
17981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            PlatformKeyboardEvent::keyIdentifierForGdkKeyCode(event->keyval),
18081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(event->keyval),
18181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            static_cast<int>(event->keyval),
18281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            0 /* macCharCode */,
18381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            false /* isAutoRepeat */,
18481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            isGdkKeyCodeFromKeyPad(event->keyval),
18581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            false /* isSystemKey */,
18681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            modifiersForEvent(reinterpret_cast<const GdkEvent*>(event)),
18781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                            gdk_event_get_time(reinterpret_cast<const GdkEvent*>(event)));
18881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
18981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
19081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch} // namespace WebKit
191